如何在 Java 中打包/加密/解包/解密一堆文件?

Posted

技术标签:

【中文标题】如何在 Java 中打包/加密/解包/解密一堆文件?【英文标题】:How to Pack/Encrypt/Unpack/Decrypt a bunch of files in Java? 【发布时间】:2009-11-13 16:15:17 【问题描述】:

我实际上是在尝试在 Java/JSP 驱动的网站上执行以下操作:

用户提供密码 密码用于构建高度加密的存档文件(zip 或其他任何文件),其中包含文本文件以及存储在服务器上的许多二进制文件。它本质上是用户文件和设置的备份。 稍后,用户可以上传文件,提供原始密码,站点将解密并解压压缩包,将提取的二进制文件保存到服务器上的相应文件夹中,然后读取文本文件以便站点可以恢复用户的旧设置和有关二进制文件的元数据。

这是构建/加密存档,然后提取其内容,我试图弄清楚如何去做。我真的不关心存档格式,除了它非常安全。

我的问题的理想解决方案将非常容易实现,并且只需要经过试验和测试的具有免费和非限制性许可证的库(例如 apache、berkeley、lgpl)。

我知道 TrueZIP 和 WinZipAES 库;前者似乎太过分了,我不知道后者有多稳定......还有其他解决方案可以很好地工作吗?

【问题讨论】:

【参考方案1】:

如果您知道如何使用 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();
     

【讨论】:

客户端将使用什么软件来解密加扰的 ZIP 文件? @PP 不要认为使用此解决方案可以做到这一点,因为文件只是一个加密的 blob。 OP表示他想控制自己的解密/解包,而不是第3方【参考方案2】:

答案已经给出(使用 Kevin 指出的密码),所以我只是对您的 topicstart 中似乎缺少的一个重要事项提出建议:确保您使用的是 HTTPS 而不是 @ 987654323@。否则,具有网络嗅探器的人将能够从数据包中获取用户提供的密码。如何做到这一点取决于相关的应用服务器。最好是参考它的文档。如果是例如 Apache Tomcat,那么您可以在 Tomcat SSL HOW-TO 中找到所有内容。

希望这会有所帮助。

【讨论】:

【参考方案3】:

虽然它可能不是特定于您的查询,但我想知道truecrypt 是否有用。您的网络服务器可以创建一个加密容器,将 zip 文件复制到该容器中。然后可以下载加密的容器。可能有点混乱,但加密应该很强大,并且下载的图像可以安装在各种操作系统上。

【讨论】:

【参考方案4】:

这里肯定有一些关于如何解决您的问题的建议,但我在回复中遗漏了一个非常重要的 BUT。对于“强加密”的任何合理定义,您不能同时满足“基于密码”和“强加密”的要求。

【讨论】:

这不一定是真的。如果您可以提供一个密码短语,它可以为您提供 256 甚至 192 位熵,您可以将其输入任何适当的分组密码 确切地说,“如果你能……”,在大多数实际情况下这是不切实际的。对英语(作为一种自然语言)熵的估计低至 0.6 位/字符,这意味着您需要一个 430 字符长的密码短语才能获得 256 位熵,这比我通常理解的要多一点作为密码。 好吧,当然,如果你让人们使用英语单词作为密码。只需设置一些简单的限制 - 例如至少需要一个大写字母和一个特殊字符——你会获得很多熵。

以上是关于如何在 Java 中打包/加密/解包/解密一堆文件?的主要内容,如果未能解决你的问题,请参考以下文章

Lua反编译流程

Lua反编译流程

使用文件打包应用程序

(java加密解密)如何实现JCE接口的各种算法??

如何使用 AES 解密用 openssl 命令加密的 Java 文件?

JAVA如何对URL进行加密和解密啊