Arun Swaminathan
Arun Swaminathan

Reputation: 351

Convert Java AES encryption to Javascript using the crypto library

Im trying to convert the java library - AESCrypt-Java to javascript.

This is my implementation so far for the decrypt function. Im not able to decrypt the text. Can someone figure out where I'm going wrong?

function decrypt(password, base64text) {
    key = generateKey(password);
    var decodedCipherText = new Buffer(base64text, 'base64')
    var iv = new Buffer(16);
    iv.fill(0);
    var decipher = crypto.createDecipheriv("aes-256-cbc", key, iv)
    let decrypted = decipher.update(decodedCipherText, 'base64', 'utf-8');
    decrypted += decipher.final('utf-8')
    return decryptedBytes
}

function generateKey(password) {
    return crypto.createHash('sha256').update(usr_id).digest();
}

var encryptedText = '1+2yFMDH1C/uIc1huwezbrsQ==';
var password      = '8AVrWtyabQ';
decrypt(password, encryptedText)

The expected plaintext output is Wordpress.

Upvotes: 0

Views: 501

Answers (1)

Andy
Andy

Reputation: 14184

You are making a few decisions that will adversely affect the security of your sensitive values:

  1. You are using a static, all-zero IV. The IV must be unique and non-predictable for every message encrypted with a specific key. The IV can then be prepended to the cipher text and transmitted unprotected to the recipient, where it is sliced and used for decryption.
  2. Your key derivation function (KDF) is weak -- SHA-256 can be cracked at 23 billion attempts per second on commodity hardware. Use a key-stretching algorithm like PBKDF2 with a high iteration count, or bcrypt or scrypt for memory hardness.
  3. Your cipher text is not authenticated -- AES/CBC provides confidentiality, but not integrity or authentication. An interceptor can manipulate the cipher text in transmission and attempt to decrypt it. This can result in unauthorized decryption (i.e. injecting malicious plaintext into your application) or a padding oracle attack, and eventually cipher text recovery. Use an authenticated encryption (with associated data) (AE or AEAD) cipher mode to mitigate this, or add a strong HMAC construction using a separate key over the cipher text and verify prior to decryption with a constant-time equals method.
  4. new Buffer(string, encoding) and new Buffer(size) are deprecated and Buffer.from(string, encoding) and Buffer.alloc(size) should be used instead. You create a Buffer containing the provided cipher text which is encoded in Base64. I have a feeling there is an issue occurring with your encoding (you don't provide any example output for us to see). Here is an example of encrypting and decrypting with Buffer objects.

    function encrypt(buffer){
      var cipher = crypto.createCipher(algorithm,password)
      var crypted = Buffer.concat([cipher.update(buffer),cipher.final()]);
      return crypted;
    }
    
    function decrypt(buffer){
      var decipher = crypto.createDecipher(algorithm,password)
      var dec = Buffer.concat([decipher.update(buffer) , decipher.final()]);
      return dec;
    }
    
    var hw = encrypt(new Buffer("hello world", "utf8"))
    // outputs hello world
    console.log(decrypt(hw).toString('utf8'));
    

    As you can see, cipher.update(buffer) handles the encoding internally so you don't need to.

Upvotes: 1

Related Questions