Once again, jasypt (“Java Simplified Encryption”) makes me smile.
Java comes with a comprehensive set of encryption utilities: JCE. I had to do some decryption the other day and ended up with this code.
public class Decryptor { private static final String ALGORITHM = "PBEWithMD5AndDES"; private final Base64 base64 = new Base64(); private final Cipher cipher; public Decryptor(String password) { try { cipher = Cipher.getInstance(ALGORITHM); // Just generate an empty salt as we don't want to use one. byte[] salt = new byte[cipher.getBlockSize()]; Arrays.fill(salt, (byte) 0); // Set up the cipher. PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray()); SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM); SecretKey key = factory.generateSecret(pbeKeySpec); PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, 1000); cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } catch (NoSuchPaddingException e) { throw new RuntimeException(e); } catch (InvalidKeySpecException e) { throw new RuntimeException(e); } catch (InvalidKeyException e) { throw new RuntimeException(e); } catch (InvalidAlgorithmParameterException e) { throw new RuntimeException(e); } } public String decrypt(String cipherText) { try { // cipherText is base64, so will always be ASCII. byte[] cipherBytes = base64.decode(cipherText.getBytes("US-ASCII")); byte[] decryptedMessage = cipher.doFinal(cipherBytes); // Assume encrypted text is UTF-8. return new String(decryptedMessage, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } catch (IllegalBlockSizeException e) { throw new RuntimeException(e); } catch (BadPaddingException e) { throw new RuntimeException(e); } } }
This does also include conversion from base64 using Apache commons-codec, but it’s a lot of code. Even though I’ve tried to make things simpler (attempting to not use a salt [and I am aware of the consequences]), there’s still a lot of baggage.
Which is why I’m so grateful to have found jasypt. Essentially, all the above code is wrapped up for you in a nice little API. The above comes down to:
SimplePBEConfig config = new SimplePBEConfig(); config.setPassword(password); config.setSaltGenerator(new ZeroSaltGenerator()); StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor(); encryptor.decrypt(cipherText);
So why did I have to write the code in the first place? Well, we need to get a 3rd party to implement it, and I can’t enforce dependencies upon them. But the difference in the amount of code is shocking.