Skip to content
Advertisement

Is there a behavioral equivalent to the AES256TextEncryptor Class of the Jasypt-Library in CryptoJS?

As a newbie to Cryptography, I’m trying to reproduce the same default behavior of the AES256TextEncryptor Class of the jasypt-library with the CrpytoJS library. This is my Java method, that basically takes in two arguments – the message that I want to encrypt as well as my secret paraphrase:

private String encryptWithAes256(String messageToBeEncrypted, String encryptorSecret) {
    AES256TextEncryptor encryptor = new AES256TextEncryptor();
    encryptor.setPassword(encryptorSecret);
    return encryptor.encrypt(messageToBeEncrypted);
}

When encrypting the messageToBeEncrypted with this code, the resulting encrypted message is fine. What I found out is that the AES256TextEncryptor, which internally uses the StandardPBEStringEncryptor as a encryptor, seems to use the PBEWithHMACSHA512AndAES_256 algorithm as a default.

How can I reproduce the same encryption behavior with CrpytoJS? When I’m trying to encrypt the message with CryptoJS in the way it’s documented here, the result is totally different from what I expect it to be.

Based on Topaco’s comment, I came up with the following JavaScript Code to mimic the Java code:

function encryptWithAes256(messageToEncrypt, encryptorKey){
      // Generate random 16 bytes salt
      var salt = CryptoJS.lib.WordArray.random(128/8);
    
      // Derive key
      var key = CryptoJS.PBKDF2(encryptorKey, salt, { keySize: 256/32, iterations: 1000 });
      console.log("derived key: " + key);
    
      // Generate random 16 bytes init vector (iv)
      var iv = CryptoJS.lib.WordArray.random(128/8);
    
      var cipherText = CryptoJS.AES.encrypt(messageToEncrypt, key, {iv: iv});
      console.log("aes encrypted text: "+ salt.toString() + iv.toString() + cipherText.toString());
      }

The generated result still seems not be as expected though, as it’s length is 88 characters, whereas the Java code generates a 64 character long encrypted message.

Advertisement

Answer

The posted code is close to the required result. The following still needs to be corrected:

  • PBKDF2 applies SHA1 by default, which means SHA512 must be explicitly specified.
  • The concatenation must be done on a binary level and not with the hex and Base64 encoded data.

If this is fixed, a possible implementation is:

function encryptWithAes256(messageToEncrypt, encryptorKey){
    // Generate random 16 bytes salt
    var salt = CryptoJS.lib.WordArray.random(128/8);
    
    // Derive key
    var key = CryptoJS.PBKDF2(
        encryptorKey, 
        salt, 
        { keySize: 256/32, iterations: 1000, hasher: CryptoJS.algo.SHA512 }     // Apply SHA512
    );                                                                         
    console.log("derived key:n" + key);
    
    // Generate random 16 bytes init vector (iv)
    var iv = CryptoJS.lib.WordArray.random(128/8);
    
    // Encrypt
    var cipherText = CryptoJS.AES.encrypt(messageToEncrypt, key, {iv: iv});
    
    // Concatenate
    var encryptedData = salt.clone().concat(iv).concat(cipherText.ciphertext);  // Concatenate on binary level
    var encryptedDataB64 = encryptedData.toString(CryptoJS.enc.Base64);         // Base64 encode the result
    console.log("aes encrypted text:n", encryptedDataB64.replace(/(.{56})/g,'$1n')); 
}

encryptWithAes256('The quick brown fox jumps over the lazy dog', 'my passphrase');
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

Since because of the random salt and IV always different data is generated, a test of the implementation is not possible by comparing the data. Instead, it must be checked whether the data generated with the CryptoJS code is decryptable with the Jasypt counterpart for decryption:

private static String decryptWithAes256(String ciphertextToBeDecrypted, String encryptorSecret) {
    AES256TextEncryptor encryptor = new AES256TextEncryptor();
    encryptor.setPassword(encryptorSecret);
    return encryptor.decrypt(ciphertextToBeDecrypted); 
}

which is indeed the case with the above CryptoJS implementation.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement