Steve,

Thanks for the help.  I finally got this working and figured I'd reply here
in case this might help others.

I found a Java implementation of EVP_BytesToKey() in the JRuby code and
borrowed it.  I ran the password through it and the key and IV I got back
didn't mach what openssl enc -d -des -p showed.  I finally realized that the
encryption was salted when I'd originally thought it was unsalted.  I pulled
the salt from the encrypted bytes and included that in the call to
EVP_BytesToKey().  That gave me a key and IV that matched what openssl
showed.  Yeah!

Unfortunately, when I tried to initialize the Cipher object with the key and
IV I got an InvalidKeyException that said the key was the wrong size.  My
key was eight bytes and matched the output from openssl exactly.  The IV was
also eight bytes and matched what openssl displayed.  I thought the problem
might have been that the key wasn't odd parity, but it still failed after I
adjusted the parity of each byte.  The Cipher transform I started with was
DES/CBC/PKCS5Padding, but I tried every combination I could think of and
nothing worked.  The bottom line is that I never was never able to get a
Cipher class initialized with with that key and IV.

However, I realized that my first experiments with
javax.cryptoPasswordBasedEncryption had been with the mistaken
assumption that there as
no salt.  I went back to my original implementation, which used the
PBEWithMD5AndDES transformation, added in the salt stuff and now it works
great.  sigh.

Interestingly, when I look inside the Key object that gets generated the key
appears to be 12 bytes long.  I haven't taken the time to look into what the
crypto classes are doing under the covers to come up with that key and why
it's different that what I got on my own.

Anyway, for those who want to do this here's the basic idea:

  int iterationCount = 1;
  byte[] salt = new byte[8];
  System.arraycopy(encrypted, 8, salt, 0, 8);
  PBEKeySpec keySpec = new PBEKeySpec( password.toCharArray(), salt,
iterationCount);
  SecretKey key = SecretKeyFactory.getInstance
("PBEWithMD5AndDES").generateSecret(keySpec);
  Cipher cipher = Cipher.getInstance(key.getAlgorithm());
  PBEParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
  cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
  byte[] plainText = cipher.doFinal(encrypted, 16,
encrypted.length-16);

  String result = new String(plainText);


--
Marc

Reply via email to