Search code examples
phprubyhmacpayu

How does this PHP function should look in Ruby? HMAC MD5


I'm working on a payment integration and I've got an example code in PHP and trying to make it work in Ruby. So far with little success. Could someone check my implementation and fix if I'm doing something wrong? Thanks.

PHP code:

/*
* HMAC HASH creation
* RFC 2104
* 
http://www.ietf.org/rfc/rfc2104.txt
* 
* @param string $key Secret key for encryption
* @param string $data String to encode
*/
function hmac($key, $data) {
 $b = 64; // byte length for md5

 if (strlen($key) > $b) {
   $key = pack("H*", md5($key));
 }

 $key = str_pad($key, $b, chr(0x00));
 $ipad = str_pad('', $b, chr(0x36));
 $opad = str_pad('', $b, chr(0x5c));
 $k_ipad = $key ^ $ipad;
 $k_opad = $key ^ $opad;

 return md5($k_opad . pack("H*", md5($k_ipad . $data)));
}

And my Ruby code:

    #Calculate HMAC MD5 PayU hash for order.
    def hmac_calculation(key, data)
      b = 64

      if key.length > b 
        key = Digest::MD5.hexdigest(key)
        key = key.pack("H*")
      end

      key = key.ljust(b, 0x00.chr)
      ipad = ''.ljust(b, 0x36.chr)
      opad = ''.ljust(b, 0x5c.chr)

      k_ipad = key ^ ipad
      k_opad = key ^ opad

      return Digest::MD5.hexdigest(k_opad + Digest::MD5.hexdigest(k_ipad + data).pack('H*'))    

    end

-- UPDATED --

Source string:

7P0499016123456192013-07-08 10:50:367sku000226Loremipsumdolorsitamet4112011102103HUF158CCVISAMC41010

Secret key:

|n4A8~!3T8^3[8%I?8@Q

Expected result:

5142968ed89754e8d3a9b9a2469d21f2

I also got this site as the reference point however the above example does not match it. http://hash.online-convert.com/md5-generator


Solution

  • There is no reason to write your own implementation of HMAC and many, many reasons not to. Just use the secure and well-tested implementation supplied by the OpenSSL module:

    require "openssl"
    
    key = "key"
    data = "Hello"
    
    digest = OpenSSL::Digest.new('md5')
    hmac = OpenSSL::HMAC.hexdigest(digest, key, data)
    

    That's literally all you need.