liferunsoncode liferunsoncode - 1 year ago 89
Ruby Question

Ruby hmac sha256 hash differs for variable versus literal

HMAC SHA256 hash generated changes when variable is used in the hashing function than using the literal.

I have to concatenate 4 parameters to generate a message string that is hashed using secret key. The concatenated message string generates a different hash than using the value of message as a literal.

require 'base64'
require 'openssl'

securityKey = 'A93reRTUJHsCuQSHR+L3GxqOJyDmQpCgps102ciuabc='
content = 'hello'
id = '1000000855'
tsp = '1460852115'
guid = '75c6016eaa1e43b4807ba25232797714'

contentmd5 = Base64.encode64(OpenSSL::Digest::MD5.digest(content))
inputString = id + tsp + guid + contentmd5
puts inputString
#Input String is

digest ='sha256')
hmac = OpenSSL::HMAC.digest(digest, securityKey, inputString)
securityToken = Base64.encode64(hmac)
puts securityToken
#Hash generated is 7ihOEZNeoJMwjLt84I8WfN5b0VwgYNOg8abPA3nZ0SM=

digest ='sha256')
hmac = OpenSSL::HMAC.digest(digest, securityKey, '1000000855146085211575c6016eaa1e43b4807ba25232797714XUFAKrxLKna5cZ2REBfFkg==')
securityToken = Base64.encode64(hmac)
puts securityToken
#Hash generated is gPNytNGMbhg8b27rklqmEK/9xjNAcOq+7nldzyDL4g0=

Answer Source

looks like Base64.encode64 appends a "\n" to the end of its output so

from docs

encode64(bin) Returns the Base64-encoded version of bin. This method complies with RFC 2045. Line feeds are added to every 60 encoded characters.


contentmd5 = Base64.encode64(OpenSSL::Digest::MD5.digest(content))






you can use strict_encode64 to not include line feeds so:

contentmd5 = Base64.strict_encode64(OpenSSL::Digest::MD5.digest(content))


 => "XUFAKrxLKna5cZ2REBfFkg=="