Search code examples
ruby-on-railsrubynode.jscryptographynode-crypto

Crypto in Nodejs and Ruby


I want crypto a string and pass to Rails app,so I find the crypto library both in Nodejs and Ruby.

In Nodejs:

var crypto = require('crypto'),
    algorithm = 'aes-256-ctr',
    password = 'd6F3Efeqd6F3Efeqd6F3Efeqd6F3Efeq';

function encrypt(text){
  var cipher = crypto.createCipher(algorithm,password)
  var crypted = cipher.update(text,'ascii',"base64")
  crypted += cipher.final("base64");
  return crypted;
}

The result is :

encrypt("1") //-输出 2g==

In Ruby

def encrypt(des_text)
    des = OpenSSL::Cipher::Cipher.new('aes-256-ctr')
    des.encrypt
    des.key = 'd6F3Efeqd6F3Efeqd6F3Efeqd6F3Efeq'
    result = des.update(des_text)
    result << des.final
    return Base64.encode64 result
end

The result is :

encrypt("1")  # 输出 1A==

So I use the same way and key to crypto a same string,Why the result is not the same?


Solution

  • Difference between crypto.createCipher(algorithm, password) and crypto.createCipheriv(algorithm, key, iv) is that password is used to derive key and IV.

    var crypto = require('crypto'),
        algorithm = 'aes-256-ctr',
        key = 'd6F3Efeqd6F3Efeqd6F3Efeqd6F3Efeq',
        iv = "1234567890123456";
    
    function encrypt(text){
      var cipher = crypto.createCipheriv(algorithm,key,iv)
      var crypted = cipher.update(text,'utf-8',"base64")
      crypted += cipher.final("base64");
      return crypted;
    }
    
    console.log(encrypt("1")); // return bQ==
    

    In Ruby, if you haven't specify iv then it will use a default iv.

    require 'openssl'
    require 'base64'
    
    def encrypt(des_text)
        des = OpenSSL::Cipher::Cipher.new('aes-256-ctr')
        des.encrypt
        des.key = 'd6F3Efeqd6F3Efeqd6F3Efeqd6F3Efeq'
        des.iv = "1234567890123456"
        result = des.update(des_text)
        result << des.final
        return Base64.encode64 result
    end
    
    p encrypt("1").strip # return bQ==