将Python的base64.b64encode(hmac.new().hexdigest())转换为Ruby

3 投票
1 回答
1475 浏览
提问于 2025-04-17 23:32

我该如何把

import base64
import hashlib
import hmac
key = ''
text = 'GET\n\n\nSat, 22 Mar 2014 13:49:42 +0000\n'
base64.b64encode(hmac.new(key, text, hashlib.sha1).hexdigest())
#=> 'ZmUxN2YxMDQxMTdlODg3MDljMTRjYjY0ZGU1NDk1MjgwNzI2Yjk1Zg=='

转换成 Ruby 1.9.3 呢?

这样做会返回不同的字符串:

require 'base64'
require 'digest'
require 'digest/hmac'
require 'cgi'
require 'openssl'
key = ''
text = 'GET\n\n\nSat, 22 Mar 2014 13:49:42 +0000\n'
hex = Digest::HMAC.hexdigest(key, text, Digest::SHA1)
Base64.urlsafe_encode64(hex)
#=> "YjdlNzBhMjFkZmRmZDFlMjM2Mzg5ZjYxYWE3NWEyZTJhN2I3MWNhMA=="

我应该怎么生成哈希,才能让它和 Python 的结果相等呢?

1 个回答

6

首先,在Ruby中,'\n'字面意思是\n。如果你想表示换行符,需要使用双引号的字符串:"\n"

另外,Digest::HMAC.hexdigest的参数顺序和Python版本是不一样的。根据Digest::HMAC的文档,它的使用是不推荐的。建议使用OpenSSL:HMAC

所以这个Ruby脚本应该这样理解:

require 'base64'
require 'openssl'
key = ''
text = "GET\n\n\nSat, 22 Mar 2014 13:49:42 +0000\n"
# hex = Digest::HMAC.hexdigest(text, key, Digest::SHA1) # <-- discouraged
hex = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), key, text)
p Base64.urlsafe_encode64(hex)
# => "ZmUxN2YxMDQxMTdlODg3MDljMTRjYjY0ZGU1NDk1MjgwNzI2Yjk1Zg=="

撰写回答