【问题标题】:Encrypting Zip Entries but not the entire Zip File in Java在 Java 中加密 Zip 条目而不是整个 Zip 文件
【发布时间】:2012-12-17 14:46:36
【问题描述】:

我知道如果我正在创建和写入一个 zip 文件,我将 ZipOutputStream 包裹在一个 OutputStream(或子类)周围,如下所示:

fos = new FileOutputStream(fileName)
zOut = new ZipOutputStream(fos);

我还知道如何创建 zip 文件以及需要指定何时添加新条目和关闭条目。我想做的是加密存档中的文件,但不加密存档,以便仍然很容易找到条目。 (部分原因是因为不同的条目将在不同的时间被读取 - 如果我加密整个 zip 文件,那么我每次都必须从头开始读取它,即使我需要的 zip 条目是第 99 个。如果整个文件被加密,我将无法随机访问条目。)

我通常知道要加密(或解密),我将一个流包裹在另一个流周围,如下所示:

fos = new FileOutputStream("ciphertext");
CipherOutputStream cos = new CipherOutputStream(fos, key);

并且我假设如果我正在写入 ZipOutputStream 并想要加密条目,以创建 ZipOutputStream,我可以执行上面第一个示例中所做的操作,然后是时候为 zip 写入数据条目,我将 ZipOutputStream 包装在 CipherOutputStream 中,如下所示:

fos = new FileOutputStream(fileName)
zOut = new ZipOutputStream(fos);
...
CipherOutputStream cos = new CipherOutputStream(zOut, key);

但这引发了几个问题:

  1. 对于这样的事情,一般来说,流的顺序重要吗?如果我将 CipherOutputStream 包装在 ZipOutputStream 中,或者我可以反过来做吗?换句话说,如果整个文件都被加密了,那么哪个流包裹在哪个流周围有关系吗?
  2. 如果我按照上述方式进行操作,并为每个条目中的数据使用 CipherOutputScream,当我需要关闭该条目并继续下一个条目时该怎么办?我可以销毁 CipherOutputStream 而不影响它所包裹的流吗?
  3. 有没有更好的方法只加密 zip 条目而不加密 zip 文件中的目录和其他数据?

【问题讨论】:

  • 请注意,加密数据的压缩效果不好。
  • @owlstead:谢谢 - 好点,我忽略了一个。我可能只是在加密之前压缩数据。我可以编辑这个类,这样就可以正常完成,所以存档本身不会被压缩,但其中的每个条目在添加之前都会被压缩。

标签: java encryption zip


【解决方案1】:

我是新来的,因此我无法对 Aaron Digulla 的帖子发表评论。这是对他的帖子的补充。

加密将数据冗余降至最低,因此加密后的压缩是无效的。压缩后的输出通常大于未压缩的输入。为防止更大的输出,请使用 0 压缩级别。仅当 zip 文件只是一个容器时,此解决方案才有效。

【讨论】:

    【解决方案2】:

    不要与流混淆。有一个流可以创建/更新磁盘上的存档文件 (ZipOutputStream)。此流未编码,因此您必须保留此代码。

    您想要的是加密各个条目的数据。因此,当您向存档添加新条目时,请照常使用 putNextEntry() 添加新条目。

    现在加载要加密的数据并创建一个写入ByteArrayOutputStreamCipherOutputStream。以这种方式编码所有数据,然后将 ByteArrayOutputStream 中的字节附加到存档中:

    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    
    CipherOutputStream cos = new CipherOutputStream(buffer, key);
    ... encode data ...
    
    byte[] data = buffer.toByteArray();
    zOut.write( data, 0, data.length );
    

    请注意,您可能希望使用ZipFile 阅读存档,因为它为您可以包装的每个条目提供了一个单独的InputStream

    【讨论】:

    • 让我重新措辞以确保我理解。不仅仅是包装流,而是将其作为一个 2 步过程来完成。首先加密数据,然后将其写入 zip 文件。然后,在另一端,从 zip 文件中获取条目数据,然后解密。对吗?
    • 是的。如果您将CipherOutputStream 直接连接到ZipOutputStream,则整个存档将被加密,您不希望这样。因此,您需要在将数据附加到存档之前对其进行加密。
    • 好的——这使得它在概念上更容易(至少在我的脑海里)。添加几行代码,但这很简单。是的,你是对的,我不能加密整个文件,因为文件会被多次提取和乱序显示,所以我必须能够跳转到一个条目并提取它。谢谢 - 我测试了它并且它正在工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    • 2020-10-07
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    相关资源
    最近更新 更多