Search code examples
javaaesencryption-symmetricpbkdf2jasypt

Using Jasypt for password based AES encryption with PBKDF2WithHmacSHA1 key


I'm implementing an encryption mechanism where I work, and the security guy's demands are as follows:

  1. Create a 256 bit key using PBKDF2WithHmacSHA512, secret password, 256bit salt and 20000 iterations minimum.
  2. Salt should be generated using SecureRandom.getInstance("SHA1PRNG");
  3. Encrypt using AES256 with the derived key.

I'm trying to use Jasypt's StandardPBEStringEncryptor class

encryptor.setPassword(PASSWORD);
encryptor.setAlgorithm("AES/CBC/PKCS5Padding");
encryptor.setKeyObtentionIterations(20000);
encryptor.setSaltGenerator(new RandomSaltGenerator());
encryptor.encrypt("something");

When I do this I get the following exception:

java.security.NoSuchAlgorithmException: AES/CBC/PKCS5Padding SecretKeyFactory not available

Am I using Jasypt incorrectly? What am I missing here?

Thanks


Solution

  • I ended up contacting Daniel Fernández who is Jasypt's lead programmer and his answer:

    I’m afraid Jasypt does not offer a way to specify different algorithms for the SecretKeyFactory and the instantiation of the Cipher itself. Sorry.

    I used this bit of java code for doing this (Without Jasypt):

    public String encrypt(final String message) {
      final byte[] salt = generateSalt();
      final Key key = createKey(salt);
    
      final Cipher encryptingCipher = createCipher(Cipher.ENCRYPT_MODE, key, salt);
      final byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8);
      final byte[] encryptedBytes = doFinal(encryptingCipher, messageBytes);
      final byte[] data = ArrayUtils.addAll(salt, encryptedBytes);
      return BaseEncoding.base64().encode(data);
    }
    
    private byte[] generateSalt() {
      final SecureRandom secureRandom = new SecureRandom();
      final byte[] salt = new byte[SALT_LENGTH];
      secureRandom.nextBytes(salt);
      return salt;
    }
    
    private Key createKey(final byte[] salt) {
      final PBEKeySpec spec = new PBEKeySpec(PASSWORD,
                                           salt,
                                           ITERATIONS,
                                           KEY_LENGTH);
      final SecretKey secretKey;
      try {
        secretKey = keyFactory.generateSecret(spec);
      } catch (final InvalidKeySpecException e) {
        throw new RuntimeException("Error creating SecretKey", e);
      }
      final SecretKeySpec result = new SecretKeySpec(secretKey.getEncoded(), ALGORITHM);
      spec.clearPassword();
      return result;
    }