我在PHP中有这个算法:
$encoded_key = 'WHllcnRGYTY3eWpUNjQ';
$decoded_key = base64_decode($encoded_key);
// XyertFa67yjT64
$params_string = implode('', $params);
//U215250.00121715620http://partner.domain.ru/order/U215/successhttp://partner.domain.ru/order/U215/fail
$raw_signature = hash_hmac('sha1', $params_string, $decoded_key, true);
// Byte-encoded, hex: c6881d8665afbb46a93a16b34bd152878a19ab3a
$encoded_signature = base64_encode($raw_signature);
// xogdhmWvu0apOhazS9FSh4oZqzo=
我正在尝试将此代码移植到Ruby并获得相同的结果,但Base64和OpenSSL无法帮助我。有谁知道什么是错的?
答案 0 :(得分:2)
一个问题是您使用的是HMAC.hexdigest
而不是HMAC.digest
。您的PHP代码生成一个原始HMAC,然后在base 64中对其进行编码。因此,您需要在Ruby中执行相同的操作。
另一个问题是密钥的基本64解码步骤。您输入的密钥未正确填充,因此将被Ruby的base 64库截断。例如:
encoded_key = "WHllcnRGYTY3eWpUNjQ"
Base64.decode64(encoded_key)
#=> "XyertFa67yjT"
# incomplete!
Base64.decode64("#{encoded_key}=\n")
#=> "XyertFa67yjT64"
# this is what you actually want
填充和最终换行确保基本64位编码数据完整,因为它标志着结束。但是,可以手动添加填充并假设数据已完成:
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"