我正在使用 ApiAuth gem(如 here 所示)来签署我的请求。我还使用 CryptoJS 编写自己的 JavaScript 代码(如 here 所示),通过检查 ApiAuth 生成的加密 header 与我的代码生成的加密 header 来提供身份验证。
下面给出的是 ApiAuth Gem 的代码片段:
def hmac_signature(headers, secret_key, options)
if options[:with_http_method]
canonical_string = headers.canonical_string_with_http_method(options[:override_http_method])
else
canonical_string = headers.canonical_string
end
digest = OpenSSL::Digest.new('sha1')
b64_encode(OpenSSL::HMAC.digest(digest, secret_key, canonical_string))
end
这是我用 JavaScript 编写的等效代码:
function hmacSignature(request, appSecret) {
return CryptoJS.HmacSHA1(canonicalString(request), appSecret).toString(CryptoJS.enc.Base64);}
这两个不会生成相同的加密 header 。我尝试使用 jsSHA 来做同样的事情,虽然 jsSHA 和 CryptoJS 生成的加密 header 是相同的,但它们与 ApiAuth 生成的加密 header 不匹配。
请帮我弄清楚如何完成这项工作。
编辑:
将规范字符串作为“消息”,将 appSecret 作为“ secret ”,我从 ApiAuth 和 CryptoJS 获得相同的值,即:
DK9kn+7klT2Hv5A6wRdsReAo3xY=
我发现原来代码中的问题是因为我的JS代码中设置的时间戳和ApiAuth中设置的时间戳不匹配。
最佳答案
我解决了我的问题,并写下这个答案,希望它能帮助其他人寻找该问题的解决方案。
- 首先我要说的是,无论是用 Ruby 还是 JS 或者任何其他语言加密,这两种加密都应该是相同的。
- 务必检查发送到两个位置的输入的每个部分是否完全相同且完全相同。
当我检查 JS 文件和 gem 的输入时,我意识到由于某种原因,时间戳(我在 JS 文件中设置的)没有正确发送到 gem。
我一步步调试我的代码,找出了错误所在。我概述了以下一些可能的问题:
我在 JS 中设置时间戳如下
request.headers["日期"]
我意识到这没有正确设置,所以我必须将“DATE”更改为“DATE1”,并相应地更改其余的代码。这有效。
- 其次,我发送的时间戳与 gem 期望的 HTTP GST 类型时间戳不兼容。这是发送时间戳时必须牢记的另一件事。
关于javascript - 匹配在 Ruby on Rails 和 JavaScript 中加密的签名 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36980835/