0

I have ruby 1.8.7 code that create hmac with sha1

key= '123'
digest = Digest::SHA1.new
digest << 'test string'
digest << key
result = digest.hexdigest
# "c1bdfd602e1581f1ab91928e2c3fd371a1e63a5c"

I want to replicate this with node.js:

key= '123';
myhmac = crypto.createHmac('sha1', key);
result = myhmac.update('test string').digest('hex');
// 'a145f4d366e9e4e96b80bc427144ba77b3c7151a'

But the result is different. What should I do in nodejs to have the same result as from ruby?

mhd
  • 4,561
  • 10
  • 37
  • 53

2 Answers2

4

You are comparing a plain SHA1 digest in your Ruby code with a HMAC (using SHA1 as its hash function) in your Node code. These are different things, although the HMAC makes use of SHA1.

Usually you would want to use the HMAC over the plain SHA1. To do that in Ruby you could do something like:

require 'openssl'

key = '123'
data = 'test string'
digest = OpenSSL::Digest::SHA1.new

# See how HMAC uses SHA1 here:
result = OpenSSL::HMAC.hexdigest(digest, key, data) 
# => "a145f4d366e9e4e96b80bc427144ba77b3c7151a", same as your node result

To reproduce your Ruby results in Node (calculating the SHA1 of the message + key), you want something like this:

const crypto = require('crypto');
const hash = crypto.createHash('sha1'); // Just SHA1, no HMAC

hash.update('test string');
hash.update('123'); // The Ruby code is hashing the concatenation of
                    // the data and key
result = hash.digest('hex');
// => 'c1bdfd602e1581f1ab91928e2c3fd371a1e63a5c', same as Ruby code
matt
  • 78,533
  • 8
  • 163
  • 197
  • Tnx very much for the help! – mhd Aug 01 '16 at 07:47
  • 1
    I don't really understand how a145f4d366e9e4e96b80bc427144ba77b3c7151a equals to c1bdfd602e1581f1ab91928e2c3fd371a1e63a5c, for me it's two different values. Can you clarify your answer please? – Paul Laffitte Apr 30 '20 at 10:45
  • @PaulLaffitte the result of my Ruby code (`a145...`) is the same as the result of the Node code _from the question_, not _my_ Node code. Similarly my Node code result (`c1bd...`) is the same as the result from the Ruby code in the question. My Ruby code gives a different result to my Node code. – matt Apr 30 '20 at 13:06
0

To make it works for both (nodejs and ruby), please make sure :

  1. (important) make it in the same format.

ruby:

payload = "{'name': 'james kachiro sarumaha', 'data': [], 'is_available': true}"
payload = payload.to_json

nodejs:

payload = "{'name': 'james kachiro sarumaha', 'data': [], 'is_available': true}"
payload = JSON.stringify(payload)
  1. have a correct key. (32)

ruby:

key = "v1tg3cOvfNdxh4TXxtdVmeB106doeQFS"

nodejs:

key = "v1tg3cOvfNdxh4TXxtdVmeB106doeQFS"

conversion

ruby :

 digest =   OpenSSL::Digest::SHA256.new
 result = OpenSSL::HMAC.hexdigest(digest, password, payload)
 #bd0724a05fab03e64e0112d09ceb11b6c1cbd8f9629a1d303e8d395d36cce396

nodejs:

 crypto.createHmac('sha256', key).update(payload).digest('hex')
 //bd0724a05fab03e64e0112d09ceb11b6c1cbd8f9629a1d303e8d395d36cce396

crypto from crypto module (nodejs core).

in my case, I'm using SHA256 but you can change it to SHA1. it will have the same result also.

tx