More than two years ago I posted this blog entry, where I showed a little utility for reading password-protected zip files in Java. Since then it seems it helped a lot of people and many asked if I could provide something for the other direction – i.e. writing encrypted files. Finally I’ve decided to add that as well as improve the original class for reading and recently I published a small open source project which provides both the ZipDecryptInputStream (for reading) as well as ZipEncryptOutputStream (for writing). The project is named ziputils and is available here: https://bitbucket.org/matulic/ziputils/overview.
The usage is very simple. ZipDecryptInputStream can be used in the same way as outlined in my old blog entry. ZipEncryptOutputStream which I added can be used in a very similar way:
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; // usage: java Main zip-file-name password filename1 [filename2 [filename3 [...]]] public class Main { public static void main(String[] args) throws IOException { // create a stream that will encrypt the resulting zip file // using the password provided in the second command line argument ZipEncryptOutputStream zeos = new ZipEncryptOutputStream(new FileOutputStream(args[0]), args[1]); // create the standard zip output stream, initialize it with our encrypting stream ZipOutputStream zos = new ZipOutputStream(zeos); // write the zip file for (int i = 2; i < args.length; i++) { ZipEntry ze = new ZipEntry(args[i]); zos.putNextEntry(ze); InputStream is = new FileInputStream(args[i]); int b; while ((b = is.read()) != -1) { zos.write(b); } zos.closeEntry(); } zos.close(); } }
You can find more about how to use the classes in the project javadoc. To download the ziputils jar, go to the project downloads page. Enjoy!
I’ve tried the encryption part, but could not decrypt the file under windows with Explorer. With Linux unzip you get the following warning:
“warning […..zip]: 4 extra bytes at beginning or within zipfile”
After drilling into the bytes and bits of the zip header structures I found out, that the offset of the central directory at the end is 4 bytes wrong. The following line should be changed:
centralRepoOffset = bytesWritten /* – ZipUtil.CFH_SIGNATURE.length*/;
I had the same problem: creating a new encrypted zip file, I was unable to open it with any zip utility program.
After I changed that line of code all works well. Thank you Heiko.
Took me a loooong time to get to this :). But now it is fixed. Thanks!
Can you modify decrypt code to process folder entries also? Now after success reading of encrypted file entry i`ve got exception in zis.closeEntry(); “ZIP not password protected.” before reading folder entry. May be it`s really simple to workaround.
I tried the code above. Zip file is created, but I’m unable to open the file. Windows states file “is invalid”.
Ideas?
it’s possible to Read the swf file direct from zip without Extract
Hi,
i added ziputils-1.1.jar mentioned in ur post to my build path as external jar…..and i copied the same code what u have mentioned in this post but i’m facing basic error
java.lang.NoClassDefFoundError: com/alutam/ziputils/ZipEncryptOutputStream
pls help me..
Please tell me how to pass to value to main method
name passwod also
thank you
Its not working when zip has sub-directories
It is now fixed.
Late to the game here but I am having an issue with
dest.write(b);
It throws….
Exception in thread “main” java.lang.IllegalStateException: Unexpected value read at offset 65: 88 (expected: 80)
at com.alutam.ziputils.ZipEncryptOutputStream.write(ZipEncryptOutputStream.java:119)
at zip.pwProtectCurrentzip.main(pwProtectCurrentzip.java:29)
Also how could we just zip up a dir with your zip class?
Thanks