Search code examples
javascriptcryptographyaescryptojspbkdf2

What is the correct way to generate AES-CBC-192 with CryptoJS?


I arrived at the following code and would like to know if this is a correct and secure way to generate an AES-CBC-192 cipher with CryptoJS:

Original Question Code:

let encrypt = (text,key) => {


    let salt = "M@Tr05K@";

    let iv = CryptoJS.lib.WordArray.random(16);

    let key_to_bits = CryptoJS.PBKDF2(key,salt,{keySize: 192/8, iterations:30000});

    return CryptoJS.AES.encrypt(text,key,{iv:iv}).toString();


}

encrypt("Lorem ipsum...","¿MinhaSenha?>Segur@?");

Code with suggested changes:

let encrypt = (text, key) => {
  let salt = CryptoJS.lib.WordArray.random(16);
  let iv = CryptoJS.lib.WordArray.random(16);
  let key_to_bits = CryptoJS.PBKDF2(key, salt, {
    keySize: 192 / 32,
    iterations: 30000
  });

  return {result : CryptoJS.AES.encrypt(text, key_to_bits, {
    iv: iv
  }).toString(),
  salt:CryptoJS.enc.Hex.stringify(salt),
  iv:CryptoJS.enc.Hex.stringify(iv)
};
}

encrypt("Lorem ipsum...", "¿MinhaSenha?>Segur@?");

Thanks for listening :)


Solution

  • here one i just finished for AES-CBC-256 from a password using PBKdf2, this is using the Web crypto api https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API

    not what you are looking for exactly but it might help with direction, remove importKey from below and read up on https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey

    function generateKey(passwd, iterations) {
    
      var encoder = new TextEncoder('utf-8');
      var passphraseKey = encoder.encode(passwd);
      var saltBuffer = encoder.encode("carthage");
    
      crypto.subtle.importKey(
        'raw',
        passphraseKey,
        {name: 'PBKDF2'},
        false,
        ['deriveBits', 'deriveKey']
      ).then(function(key) {
    //    console.log(key);
        return window.crypto.subtle.deriveKey(
        { "name": 'PBKDF2',
          "salt": saltBuffer,
          "iterations": iterations,
          "hash": 'SHA-256'
        },
        key,
        { "name": 'AES-CBC',
          "length": 256
        },
        true,
        [ "encrypt", "decrypt" ]
      )
      }).then(function (webKey) {
    //    console.log(webKey);
        return crypto.subtle.exportKey("raw", webKey);
      }).then(function (buffer) {
    //    console.log(buffer);
    //    console.log(saltBuffer);
        console.log("Private Key = " + buf2hex(buffer));
        console.log("Salt = " + bytesToHexString(saltBuffer));
      });
    
    
    }
    
    
    function buf2hex(buffer) { // buffer is an ArrayBuffer
      return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
    }
    
    function bytesToHexString(byteArray) {
      return Array.prototype.map.call(byteArray, function(byte) {
        return ('0' + (byte & 0xFF).toString(16)).slice(-2);
      }).join('');
    }