Jasypt++

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.

Comments are Closed