Node.js and crypto library

23,904

Solution 1

You need to store the return from cipher.update as well as cipher.final to be sure you have everything.

cipher.update "returns the enciphered contents, and can be called many times with new data as it is streamed":

http://nodejs.org/docs/v0.2.5/api.html#cipher-update-247

cipher.final "returns any remaining enciphered contents".

I think you just append the results with each call like this:

var crypto = require('crypto');
var cipher = crypto.createCipher('aes-256-cbc','InmbuvP6Z8');
var text = "123|123123123123123";
var crypted = cipher.update(text,'utf8','hex');
crypted += cipher.final('hex');
var decipher = crypto.createDecipher('aes-256-cbc','InmbuvP6Z8');
var dec = decipher.update(crypted,'hex','utf8');
dec += decipher.final('utf8');

I get '12443a347e8e5b46caba9f7afc93d71287fbf11169e8556c6bb9c51760d5c585' for crypted and '123|123123123123123' for dec in the above with node v0.2.5

Solution 2

RandomEtc is correct, but just in case anyone stumbling on this question is using 'base64' as their encoding: Don't. Stick to 'hex'. At least as of 0.4.2, there's a bug that can result in corrupted data when 'base64' is used. See: https://github.com/joyent/node/issues/738/

Solution 3

Please note that the += operator will not work in later versions of node.js. Please follow the advice given in Node.js Crypto class returning different results with updated version and use Buffer.concat()

Share:
23,904
Mike
Author by

Mike

Updated on June 27, 2020

Comments

  • Mike
    Mike almost 4 years

    I'm having weird issues with Node's crypto library. I wrote this simple AES testing script:

    var cipher = crypto.createCipher('aes-256-cbc','InmbuvP6Z8')
    var text = "123|123123123123123";
    cipher.update(text,'utf8','hex')
    var crypted = cipher.final('hex')
    var decipher = crypto.createDecipher('aes-256-cbc','InmbuvP6Z8')
    decipher.update(crypted,'hex','utf8')
    var dec = decipher.final('utf8')
    

    When I do console.log(dec), it's null. For some reason if I set test to "123|123123", it works. So why does "123|123123" work but "123|123123123123123" doesn't?

  • Vanwaril
    Vanwaril over 13 years
    RandomEtc is correct, remember that in node.js, everything is streamlined for, well, streams. The hash and cipher functions can be updated with text any number of times, which just adds text to it, but to get the result, you have to do a hash.digest or cipher.final
  • James P. Wright
    James P. Wright almost 13 years
    RandomEtc, thanks for your answer to this. It got me there on crypto stuff finally! :)
  • Suresh Pattu
    Suresh Pattu over 4 years
    @RandomEtc. Can you help me to convert this code to javascript?
  • Suresh Pattu
    Suresh Pattu over 4 years
    Cipher cipher = Cipher.getInstance(ALGORITHM); byte[] messageArr = message.getBytes(); SecretKeySpec keySpec = new SecretKeySpec(Base64.getDecoder().decode(key), "AES"); byte[] ivParams = new byte[16]; byte[] encoded = new byte[messageArr.length + 16]; System.arraycopy(ivParams, 0, encoded, 0, 16); System.arraycopy(messageArr, 0, encoded, 16, messageArr.length); cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(ivParams));
  • Suresh Pattu
    Suresh Pattu over 4 years
    byte[] encryptedBytes = cipher.doFinal(encoded); encryptedBytes = Base64.getEncoder().encode(encryptedBytes); return new String(encryptedBytes);