One problem is that you are using HMAC.hexdigest
instead of HMAC.digest
. Your PHP code is generating a raw HMAC and then encoding it in base 64. Therefore, you need to do the same thing in Ruby.
The other problem is the base 64 decoding step of the key. The key you entered is not padded correctly and will therefore be truncated by Ruby's base 64 library. For example:
encoded_key = "WHllcnRGYTY3eWpUNjQ"
Base64.decode64(encoded_key)
#=> "XyertFa67yjT"
# incomplete!
Base64.decode64("#{encoded_key}=\n")
#=> "XyertFa67yjT64"
# this is what you actually want
The padding and the final newline are there to ensure that the base 64 encoded data is complete, since it marks the end. However, it is possible to manually add the padding and just assume that the data is complete:
require 'base64'
require 'openssl'
def base64_pad(unpadded_str)
padding = case unpadded_str.size % 3
when 1 then "=="
when 2 then "="
end
"#{unpadded_str}#{padding}\n"
end
encoded_key = "WHllcnRGYTY3eWpUNjQ"
key = Base64.decode64(base64_pad(encoded_key))
#=> "XyertFa67yjT64"
string = "U215250.00121715620http://partner.domain.ru/order/U215/successhttp://partner.domain.ru/order/U215/fail"
Base64.encode64(OpenSSL::HMAC.digest('SHA1', key, string))
#=> "xogdhmWvu0apOhazS9FSh4oZqzo=\n"