Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

AES-256-CBC with Digest from Ruby to NodeJS

AES-256-CBC with Digest from Ruby to NodeJS

Problem

I am hoping someone can shed some light on a problem that has been vexing me for the last few hours.

I am trying to decode a string that has been encoded in Ruby thus:

#!/usr/bin/env ruby

require 'base64'
require 'openssl'
require 'openssl/cipher'
require 'openssl/digest'

aes = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
aes.encrypt
aes.key = Digest::SHA256.digest('IHazSekretKey') 

p Base64.encode64( aes.update('text to be encrypted') 

Executing the above spits out: "3P86KyOrN2QJ/HFxxo3b7kAsxTgpDMMjROUPclsuXj0=\n"

I now try to decrypt this string in NodeJS 0.6.17

#!/usr/bin/env node

var crypto = require('crypto'); 

function decrypto(toDecryptStr) {
  var result,
    encoded   = new Buffer(toDecryptStr, 'base64'),
    decodeKey = crypto.createHash('sha256').update('IHazSekretKey', 'ascii').digest(),
    decipher  = crypto.createDecipher('aes-256-cbc', decodeKey);

  result = decipher.update(encoded);
  result += decipher.final();

  return result;
};

console.log(decrypto('3P86KyOrN2QJ/HFxxo3b7kAsxTgpDMMjROUPclsuXj0='));
console.log(decrypto('3P86KyOrN2QJ/HFxxo3b7kAsxTgpDMMjROUPclsuXj0=\n')

The second script yields:

[email protected]:~/tmp/tst$ ./js_decrypt 
Å'{ H£V)ÜB
Å'{ H£V)ÜB

Any help would be very much appreciated as my only remaining option now is to drown myself in a barrel of [Jamerson || Kirin Ichiban] (I'm only kidding)

PS there is a similar question on SO here, which sadly hasn't yielded any inspiration for my case.

Problem courtesy of: Nazar

Solution

The critical missing piece is the IV, which is required when encryption/decryption is to be made across language boundaries as apparently the encrypter will generate a random IV (or something like that - still don't understand how Ruby decrypts the string without an IV.... but then what do I know....), if one is not provided.

The following snippets show how to encrypt a string in Ruby and decrypt in NodeJS.

#!/usr/bin/env ruby

require 'openssl'
require 'base64'
require 'openssl/cipher'
require 'openssl/digest'

aes = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
aes.encrypt
aes.key = Digest::SHA256.digest('IHazSekretKey') 
aes.iv  = '1234567890123456'

p Base64.encode64( aes.update('text to be encrypted') 

The above prints: "eiLbdhFSFrDqvUJmjbUgwD8REjBRoRWWwHHImmMLNZA=\n"

#!/usr/bin/env node

var crypto = require('crypto'); 

function decrypto(toDecryptStr) {
  var result,
    encoded   = new Buffer(toDecryptStr, 'base64'),
    decodeKey = crypto.createHash('sha256').update('IHazSekretKey', 'ascii').digest(),
    decipher  = crypto.createDecipheriv('aes-256-cbc', decodeKey, '1234567890123456');

  result = decipher.update(encoded);
  result += decipher.final();

  return result;
}

console.log(decrypto('eiLbdhFSFrDqvUJmjbUgwD8REjBRoRWWwHHImmMLNZA=\n'))

The JS script now properly decrypts the string.

One unfortunate side effect is that existing encrypted data will need to be decrypted and then re-encrypted with an IV that is then used in the decrypting implementation.

A PITA but nonetheless a working solution.

Solution courtesy of: Nazar

Discussion

View additional discussion.



This post first appeared on Node.js Recipes, please read the originial post: here

Share the post

AES-256-CBC with Digest from Ruby to NodeJS

×

Subscribe to Node.js Recipes

Get updates delivered right to your inbox!

Thank you for your subscription

×