如何打包/加密/解压缩/ Java解密一堆文件?
我基本上是试图做在Java/JSP驱动的网站如下:如何打包/加密/解压缩/ Java解密一堆文件?
- 用户提供了密码
- 密码被用来建立一个强加密的档案文件(ZIP,或任何其他)包含一个文本文件以及存储在服务器上的许多二进制文件。它本质上是用户文件和设置的备份。
- 稍后,用户可以上传文件,提供原始密码,网站将解密并解压缩存档,将提取的二进制文件保存到服务器上相应的文件夹中,然后阅读文本文件,以便网站可以恢复用户关于二进制文件的旧设置和元数据。
这是建筑/加密档案,然后提取其内容,我试图找出如何做。我真的不关心档案格式,除非它非常安全。
我的问题的理想解决方案将很容易实现,并且只需要经过免费和非限制性许可证(例如apache,berkeley,lgpl)的久经考验的库。
我知道TrueZIP和WinZipAES库;前者似乎是大规模的矫枉过正,我不能说出后者有多稳定......是否还有其他解决方案能够很好地工作?
如果你知道如何使用java.util.zip包来创建一个zip文件,你可以创建一个PBE Cipher并传递到CipherOutputStream或CipherInputStream(取决于如果你正在读或写)。
下面应该让你开始:
public class ZipTest {
public static void main(String [] args) throws Exception {
String password = "password";
write(password);
read(password);
}
private static void write(String password) throws Exception {
OutputStream target = new FileOutputStream("out.zip");
target = new CipherOutputStream(target, createCipher(Cipher.ENCRYPT_MODE, password));
ZipOutputStream output = new ZipOutputStream(target);
ZipEntry e = new ZipEntry("filename");
output.putNextEntry(e);
output.write("helloWorld".getBytes());
output.closeEntry();
e = new ZipEntry("filename1");
output.putNextEntry(e);
output.write("helloWorld1".getBytes());
output.closeEntry();
output.finish();
output.flush();
}
private static Cipher createCipher(int mode, String password) throws Exception {
String alg = "PBEWithSHA1AndDESede"; //BouncyCastle has better algorithms
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(alg);
SecretKey secretKey = keyFactory.generateSecret(keySpec);
Cipher cipher = Cipher.getInstance("PBEWithSHA1AndDESede");
cipher.init(mode, secretKey, new PBEParameterSpec("saltsalt".getBytes(), 2000));
return cipher;
}
private static void read(String password) throws Exception {
InputStream target = new FileInputStream("out.zip");
target = new CipherInputStream(target, createCipher(Cipher.DECRYPT_MODE, password));
ZipInputStream input = new ZipInputStream(target);
ZipEntry entry = input.getNextEntry();
while (entry != null) {
System.out.println("Entry: "+entry.getName());
System.out.println("Contents: "+toString(input));
input.closeEntry();
entry = input.getNextEntry();
}
}
private static String toString(InputStream input) throws Exception {
byte [] data = new byte[1024];
StringBuilder result = new StringBuilder();
int bytesRead = input.read(data);
while (bytesRead != -1) {
result.append(new String(data, 0, bytesRead));
bytesRead = input.read(data);
}
return result.toString();
}
}
答案已经给出(使用的密码凯文指出的),所以我只能做一个建议,关于这似乎是缺少一个重要的问题您的topicstart:确保您使用HTTPS
而不是HTTP
。否则,使用网络嗅探器的用户将能够从数据包中获取用户提供的密码。如何做到这一点取决于有问题的应用程序服务器。最好的是参考它的文档。如果它是例如Apache Tomcat,那么您可以在Tomcat SSL HOW-TO中找到所有内容。
希望这会有所帮助。
虽然它可能不是特定于您的查询,我不知道是否truecrypt可能有用。你的网络服务器可以创建一个加密的容器,压缩文件将被复制到其中。然后可以下载加密的容器。可能有点麻烦,但加密应该很强大,下载的映像可以安装在各种操作系统上。
这里肯定有一些关于如何解决你的问题的建议,但是我在答复中错过了一个很大的答案。对于“强加密”的任何合理定义,您无法同时实现“基于密码”和“强加密”。
这不一定是真的。如果你可以提供给你256个甚至192比特熵的密码短语,你可以将它提供给任何适当的块密码。 – Kevin 2009-11-13 17:15:34
准确地说,“如果你可以......”并且在大多数实际情况下不切合实际。英语熵(作为一种自然语言)的估计低至0.6位/字符,这意味着你需要一个430字符长的短语来处理256位熵,这比我通常理解的要多一点作为密码。 – jarnbjo 2009-11-13 18:02:19
当然,如果你让人们使用英文单词作为密码。只要加上一些简单的限制 - 例如至少需要一个大写字母和一个特殊字符 - 并且你获得了很多熵。 – DanM 2009-11-18 13:14:40
客户端将使用什么软件来解密已加密的ZIP文件? – 2009-11-13 16:58:36
@PP不要以为这个解决方案可以做到这一点,因为这个文件只是一个加密的blob。 OP表示他想控制解密/解包自己,而不是第三方 – Kevin 2009-11-13 17:09:58