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

时间:2013-01-03 08:46:11

标签: java encryption zip

我知道如果我正在创建并写入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文件中的目录和其他数据?

2 个答案:

答案 0 :(得分:3)

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

您想要的是加密各个条目的数据。因此,当您向归档添加新条目时,请像往常一样添加一个putNextEntry()的新条目。

现在加载数据以加密并创建写入CipherOutputStream的{​​{1}}。以这种方式对所有数据进行编码,然后将ByteArrayOutputStream中的字节附加到存档:

ByteArrayOutputStream

请注意,您可能希望使用ByteArrayOutputStream buffer = new ByteArrayOutputStream(); CipherOutputStream cos = new CipherOutputStream(buffer, key); ... encode data ... byte[] data = buffer.toByteArray(); zOut.write( data, 0, data.length ); 阅读存档,因为它为您可以包装的每个条目提供了个人ZipFile

答案 1 :(得分:0)

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

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