在Java中加密Zip条目但不加密整个Zip文件

3
我知道如果我要创建和写入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. 如果按照上述方法,在每个条目的数据中使用CipherOutputStream,当我需要关闭该条目并转到下一个时,我该怎么办?我可以销毁CipherOutputStream而不影响它所包装的流吗?
  3. 是否有更好的方法仅加密zip条目而不加密zip文件中的目录和其他数据?

请注意,加密数据不易压缩。 - Maarten Bodewes
@owlstead:谢谢你,说得好,这是我忽视的一个问题。在加密之前,我可以将数据压缩。我可以编辑类,使其在正常情况下完成,并且存档本身不被压缩,但在添加之前,其中的每个条目都会被压缩。 - Tango
2个回答

3
不要混淆流。有一个创建/更新磁盘上存档文件的流(ZipOutputStream)。这个流没有编码,所以你必须不去动它。
你想要的是加密每个条目的数据。因此,当你像往常一样使用putNextEntry()添加新条目到存档中时,请加载要加密的数据并创建一个写入ByteArrayOutputStream的CipherOutputStream。以这种方式编码所有数据,然后将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,您可以将其包装起来。

让我重新表述以确保我理解正确。不要仅仅包装流,而是将其作为两个步骤进行。首先加密数据,然后将其写入zip文件。然后,在另一端,从zip文件获取条目数据,并在此之后对其进行解密。是这样吗? - Tango
是的。如果您直接将CipherOutputStream连接到ZipOutputStream,整个归档文件都将被加密,而您不希望这样。因此,在将数据附加到归档文件之前,您需要对其进行加密。 - Aaron Digulla
好的 - 这在概念上使它更容易(至少在我的脑海中)。增加了几行代码,但这很微不足道。是的,你说得对,我不能加密整个文件,因为文件将被多次提取和显示出来,所以我必须能够跳转到一个条目并提取它。谢谢 - 我测试过了,它正在工作。 - Tango

0

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

加密将数据冗余降至最低,因此加密后的压缩效果不佳。压缩后的输出通常比未压缩的输入还要大。为避免输出变大,请使用0压缩级别。仅当zip文件只是容器时,此解决方案才有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接