[izpack-devel] Ideas For Possible Encryption Feature (and Request for Suggestions)

Hal Vaughan hal at thresholddigital.com
Fri Jan 27 18:33:42 CET 2006


I want to use the web installer for my program, so I don't have to send my 
clients CDs and can just have them run it from the web.  That means the 
software is available on the web and even if I protect it, there is still the 
possibility of hackers (however unlikely) gaining access.  I know I am not 
alone in thinking it would be nice if the programs in an IzPack install jar 
file could be encrypted and when the program is installed, it asks the end 
user for a password.  That password is used to decrypt the data before it is 
written to the disk as it is installed.  This would allow developers to 
create relatively secure install files of their software that they can be 
reasonably sure can only be obtained by their clients.

I have just reinstalled Debian my workstation, and do not yet have Eclipse 
running, so I may reference the wrong classes here and cannot provide line 
numbers, but this is just a general outline and I'm not at the point where I 
want to get too detailed yet.

The encryption settings would require EncryptionSpec.xml, which could 
essentially contain a list of which packs to encrypt and the password needed 
to decrypt them.  (The password would NOT be plain text.  More on that 
later.)   Encryption would be done by an IO stream, so the Packer class would 
handle it with minimal modifications.  Most of the work for this would be in 
a separate class (for now, let's call it IzCrypt).  As the Packer iterates 
through each pack to include in the install jar, it would pass the 
compression stream to IzCrypt with the pack name or number.  IzCrypt would 
determine if the pack is encrypted.  If so, it would wrap an encryption 
stream around the ZipOutputStream, THEN wrap the other output stream around 
that and returns the final output stream.  If it is NOT to be encrypted, it 
just wraps the output stream around the ZipOutputStream stream and returns 
that stream.

This would mean the Packer class would not have to do anything else to handle 
any encryption.  It would simply instantiate the IzCrypt class and call it 
for each pack to get the output stream.  It doesn't even need to know if the 
output stream is being encrypted.  I understand that there might be a concern 
about this changing the format of the zip archives the packs are stored in. 
The stored packs would not appear to be in a zip archive, but just files 
stored in the install jar.

When the Unpacker class unpacks each pack, it works in the same way.  It 
instantiates the IzCrypt class and as it iterates through each pack, it calls 
a method in IzCrypt with the input stream and the pack name or number.  
IzCrypt determines if the pack is encrypted.  If so, it wraps the decryption 
stream around it, THEN wraps the ZipInputStream and returns the 
ZipInputStream for the Unpacker to use to read the pack.  If the pack is not 
encrypted, it just wraps the ZipInputStream around the input stream and 
returns that.  Again, just as in the Packer class, there is no need for the 
Unpacker class to even know if the pack is encrypted. Either way, it reads 
the pack data from the ZipInputStream.

It would not matter that the packs are stored in the jar in a file that 
doesn't even resemble a zip archive, since the only class that needs to read 
them would have an IO stream decrypting the data before the ZipInputStream 
reads it.  This might even help, since it would mean anyone trying to decode 
the pack files would have to take all the time to read IzPack code to 
determine the files are actually encrypted zip files.

This leaves one point left: the password.  The password would not be in 
EncryptionSpec.xml, but would be in a separate file, by itself, so it is 
never included in the install jar.  I was even planning on writing a utility 
class that would read this password, then store the hashed form of the 
password in EncryptionSpec.xml.  When the pack is compiled, IzCrypt would 
read the password file and use it for encrypting the data.  
EncryptionSpec.xml would be stored as a resource in the install jar, which 
means the hashed form of the password would be available.

The only thing the end user ever sees of all this is the DecryptPanel, which 
would ask him for his password (which would be sent to him by some channel 
other than the way the install jar was distributed).  When the password is 
entered, IzCrypt would create a hash and compare it to the stored hashed 
version of the password.  If they match, it stores the plain text password in 
InstallData.  (Otherwise, a "You cannot proceed without the correct password" 
message would be appropriate.)  When the Unpacker class instantiates IzCrypt, 
it passes it the InstallData class that all the panels have used as a 
parameter, so IzCrypt has the password available for decrypting the packs.

There is one catch, and I do not know if it is an issue to IzPack developers.  
I've looked around for Java implementations of the Unix Crypt() function.  
I'm not a cryptography expert (I just use it when I have to).  I do know that 
this function is non-reversable and creates password hashses that can NOT be 
used to determine the original password.  There are Java implementations of 
the class, but they are under a more permissive licensing than Apache 2.0, 
which would mean in the licensing statements for IzPack, a line like, "IzPack 
is liscenses under the Apache 2.0 license, except for the EncryptPassword 
class, which is based on work by Wes Biggs and is licensed under the BSD 
License.  See EncryptPassword.java in the source for details."

I do not know if that is a big issue or not.  I have already written Wes to 
make verify the licensing and ask about using the class.  (The original 
source for his class was posted on the Internet, clearly with the intent of 
allowing re-use.  His class was based on a class by John Dumas, which is 
based on Crypt in C (or C++, forgot which) by Eric Young.)  If there is a 
Java class, either built in or freely available, which will do the same 
thing, I would certainly be glad to use it instead.  I'm open to suggestions.

I've already written another panel which could benefit from the use of a class 
that does this kind of hashing so the password for it would not have to be 
stored in plain text or in an easily decrypted form in the install jar.

As with the other work I've been doing for my use of IzPack, I would be making 
this available for inclusion in the IzPack distribution.  (I've got several 
other panels, in various stages of completion.)  Basically it would be 
invisible and 100% ignorable to anyone creating non-encrypted installs, but 
would be easily set up for those that would like encrypted installs.

If anyone has comments, either about the idea of encryption or about the 
licensing questions (or potential issue), I'd like to hear them.

Thank you!

Hal



More information about the izpack-devel mailing list