From: Roodzant, M. <Mar...@Ge...> - 2006-06-21 07:29:49
|
Hi, I have the following problem: We have just recently upgraded our application from jdk1.3 to jdk1.5. In jdk1.3 we used cryptix-3.2.0.jar and the following encryptiong: // getting the cipher java.security.Security.addProvider(new = cryptix.provider.Cryptix()); cipher =3D = Cipher.getInstance(Cipher.getInstance("Blowfish", "Cryptix") , (Mode) Mode.getInstance("CFB", "Cryptix") , PaddingScheme.getInstance("OneAndZeroes")); // encrypting RawSecretKey privateKey =3D new RawSecretKey("Blowfish", = Hex.fromString(encryptionkey)); cipher.initEncrypt(privateKey); byte[] ect =3D cipher.crypt(plain.getBytes()); // decrypting privateKey =3D new RawSecretKey("Blowfish", = Hex.fromString(encryptionkey)); cipher.initDecrypt(privateKey); byte[] dct =3D cipher.crypt(Hex.fromString(secret)); Now we use jdk1.5, with the set of cryptix-jce-xxx jars = (cryptix-jce-api.jar,cryptix-jce-compat.jar,cryptix-jce-provider.jar, = cryptix-jce-tests.jar) and the 'unlimited strength' versions of = local_policy.jar and US_export_policy.jar. The following code works in itself but does NOT give the same cipher as = before, which is a problem because we have encrypted values stored in a = database. These we still cannot decrypt propertly. public class PasswordUtil { private static Log log =3D = LogFactory.getLog(PasswordUtil.class.getName()); private static String default_key =3D CryptNames.ENCRYPTION_KEY; /** * Get the cipher to use for encryption or decryption */ private static Cipher getCipher(int mode, String encryptionKey ) { log.debug("PasswordUtil::getCipher()"); Cipher cipher =3D null; try { byte[] raw =3D encryptionKey.getBytes(); SecretKeySpec skeySpec =3D new SecretKeySpec(raw, = "Blowfish"); System.out.println("PasswordUtil::getCipher - got = secretKey "); cipher =3D Cipher.getInstance("Blowfish/CFB/NoPadding"); // cipher =3D = Cipher.getInstance("Blowfish/CFB/NoPadding", new = cryptix.jce.provider.CryptixCrypto()); System.out.println("PasswordUtil::getCipher - got = instance "); byte[] IV =3D new byte[8]; IvParameterSpec IVspec =3D new IvParameterSpec( IV ); cipher.init(mode, skeySpec, IVspec); System.out.println("PasswordUtil::getCipher - = initialized cipher "); log.debug("PasswordUtil::getCipher - Got Cipher = instance"); System.out.println("PasswordUtil::getCipher - Got Cipher = instance"); } catch (java.security.NoSuchAlgorithmException e) { log.fatal("PasswordUtil::getCipher - Encryption = Algorithm not found - null will be returned ", e); System.out.println("PasswordUtil::getCipher - Encryption = Algorithm not found - null will be returned"); e.printStackTrace(); } catch ( NoSuchPaddingException e ) { log.fatal("PasswordUtil::getCipher - Padding not found - = null will be returned", e); System.out.println("PasswordUtil::getCipher - Padding = not found - null will be returned"); e.printStackTrace(); } catch ( InvalidKeyException e ) { log.fatal("PasswordUtil::getCipher - InvalidKey - null = will be returned", e); System.out.println("PasswordUtil::getCipher - InvalidKey = - null will be returned"); e.printStackTrace(); } catch ( InvalidAlgorithmParameterException e ) { log.fatal("PasswordUtil::getCipher - = InvalidAlgorithmParameter - null will be returned", e); System.out.println("PasswordUtil::getCipher - = InvalidAlgorithmParameter - null will be returned"); e.printStackTrace(); //To change body of catch = statement use File | Settings | File Templates. } log.debug("PasswordUtil::getProvider():Finished"); System.out.println("PasswordUtil::getProvider():Finished"); return cipher; } /** * Decrypt string * * @param secret Encrypted text. * @return plain (decrypted) text */ private static String decrypt(String secret) { log.debug("decrypt()::Started"); return decrypt(secret, default_key); } private static String decrypt(String secret, String key) { log.debug("decrypt()::Started"); String plain =3D null; try { Cipher cipher =3D getCipher(Cipher.DECRYPT_MODE, key); log.debug("PasswordUtil::decrypt()::Initialized = decryption"); byte[] dct =3D cipher.doFinal(Hex.decode(secret)); plain =3D new String(dct); } catch (Exception e) { log.fatal("PasswordUtil::Failed to decrypt", e); } log.debug("PasswordUtil::decrypt()::Returning " + plain); log.debug("PasswordUtil::decrypt()::Finished"); return plain; } /** * Encrypt a string * * @param plain plain text string * @return an encrypted string */ private static String encrypt(String plain) { log.debug("encrypt()::Started"); return encrypt(plain, default_key); } private static String encrypt(String plain, String key) { log.debug("encrypt()::Started"); String encrypted =3D null; try { Cipher cipher =3D getCipher(Cipher.ENCRYPT_MODE, key); log.debug("encrypt()::Initialized encryption"); byte[] dct =3D cipher.doFinal(plain.getBytes()); encrypted =3D Hex.encode(dct); log.debug("encrypt()::Crypting " + plain); } catch ( Exception e ) { log.fatal("PasswordUtil::Failed to encrypt", e); } log.debug("decrypt()::Returning " + encrypted); log.debug("encrypt()::Finished"); return encrypted; } public static void main( String[] args ) { String cipher =3D encrypt("ttmjb6f5"); String cipherInStorage =3D "965C23639DAF690B"; String cleartext =3D decrypt(cipher); String cleartextFromStorage =3D decrypt(cipherInStorage); System.out.println("cleartext : ttmjb6f5"); System.out.println("cipherInStorage : 965C23639DAF690B"); System.out.println("encrypted : "+cipher); System.out.println("decrypted : "+cleartext); System.out.println("decrypted ldap value: "+cleartextFromStorage); } } The result of the main is: cleartext : ttmjb6f5 cipherInStorage : 965C23639DAF690B encrypted : 7e5567be2369a2cc decrypted : ttmjb6f5 decrypted ldap value: oe})=B7=DC=F0=F2 There are two issues here: 1. I cannot find any Provider (not even Cryptix) that allows the = OneAndZeroes padding (I used NoPadding here to get any result at all) 2. To decrypt using Blowfish/CFB you MUST provide a byte[] (IV). When = encrypting en when decrypting the same byte[] must be used. The old code = does not use this byte[] so I have no idea what byte[] to use to get a = correct decryption. Does anyone know how to make a code that works and provides the right = encryption and decryption using JCE? Or if this is possible at all? If it is not possible I can look at alternative courses of action. thanks in advance for any input Marjon |