Reputation: 669
I know if I'm creating and writing to a zip file, I wrap the ZipOutputStream around an OutputStream (or subclass), like this:
fos = new FileOutputStream(fileName)
zOut = new ZipOutputStream(fos);
I also know how to create a zip file and the need to specify when I'm adding a new entry and to close an entry. What I'd like to do is encrypt the files within the archive, but leave the archive unencrypted so the entries are still easily found. (Part of the reason for this is because different entries will be read at different times - and if I encrypt the entire zip file, then I'll have to start reading it at the start every time, even if the zip entry I need is the 99th one. I won't have random access to entries if the entire file is encrypted.)
I know normally to encrypt (or decrypt), I wrap one stream around the other like this:
fos = new FileOutputStream("ciphertext");
CipherOutputStream cos = new CipherOutputStream(fos, key);
And I presume if I'm writing to a ZipOutputStream and want to encrypt the entry, to create the ZipOutputStream, I could do what I did above in the first example, and then when it's time to write the data for a zip entry, I wrap the ZipOutputStream within the CipherOutputStream, like this:
fos = new FileOutputStream(fileName)
zOut = new ZipOutputStream(fos);
...
CipherOutputStream cos = new CipherOutputStream(zOut, key);
But that raises a few questions:
Upvotes: 3
Views: 2997
Reputation: 1
I'm new here, thus I can't write comment to Aaron Digulla's post. This is a supplement to his post.
The encryption decreases the data redundancy to the minimum, therefore the compression after encryption is ineffective. The compressed output usually bigger than the uncompressed input. To prevent a bigger output, use 0 compression level. This solution is good only if the zip file just a container.
Upvotes: 0
Reputation: 328584
Don't get confused with the streams. There is a stream which creates/updates the archive file on disk (ZipOutputStream
). This stream isn't encoded, so you must leave this code alone.
What you want is to encrypt the data of the individual entries. So when you add a new entry to the archive, add a new entry with putNextEntry()
as usual.
Now load the data to encrypt and create a CipherOutputStream
that writes to a ByteArrayOutputStream
. Encode all the data this way and then append the bytes from the ByteArrayOutputStream
to the archive:
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
CipherOutputStream cos = new CipherOutputStream(buffer, key);
... encode data ...
byte[] data = buffer.toByteArray();
zOut.write( data, 0, data.length );
Note that you probably want to read the archive using ZipFile
because it gives you an individual InputStream
for each entry that you can wrap.
Upvotes: 3