Php node.js hmac.digest()输出似乎错误

Php node.js hmac.digest()输出似乎错误,php,facebook,authentication,node.js,facebook-graph-api,Php,Facebook,Authentication,Node.js,Facebook Graph Api,我试图用node.js实现一个Facebook库,但请求签名不起作用。我已经将PHP示例翻译成node。我正在用这里给出的例子进行测试,其中的秘密是字符串“secret”。我的代码如下所示: var signedRequest = request.signed_request.split('.'); var sig = b64url.decode(signedRequest[0]); var expected = crypto.createHmac('sha256', 'secret').u

我试图用node.js实现一个Facebook库,但请求签名不起作用。我已经将PHP示例翻译成node。我正在用这里给出的例子进行测试,其中的秘密是字符串“secret”。我的代码如下所示:

var signedRequest = request.signed_request.split('.');

var sig = b64url.decode(signedRequest[0]);

var expected = crypto.createHmac('sha256', 'secret').update(signedRequest[1]).digest();

console.log(sig == expected); // false
我不能
console.log
解码字符串本身,因为它们有特殊字符,导致控制台清除(如果您有建议,请告诉我),但我可以输出它们的b64url编码

正如您在FB文档中看到的,预期的编码sig是

vlXgu64BQGFSQrY0ZcJBZASMvYvTHu9GQ0YM9rjPSso
编码时,我的
预期值为

wr5Vw6DCu8KuAUBhUkLCtjRlw4JBZATCjMK9wovDkx7Dr0ZDRgzDtsK4w49Kw4o
那么为什么我认为这是
digest
错了呢?也许错误在我这边?好吧,如果我用PHP执行文档中给出的确切示例,就会得到正确的结果。但是如果我改变hash_hmac调用,使最后一个参数为false,输出十六进制,我得到

YmU1NWUwYmJhZTAxNDA2MTUyNDJiNjM0NjVjMjQxNjQwNDhjYmQ4YmQzMWVlZjQ2NDM0NjBjZjZiOGNmNGFjYQ==
现在,如果我回到javascript代码,将hmac代码更改为
.digest(“hex”)
而不是默认的
“binary”
,并记录结果的base64编码,我会得到。。。惊喜

YmU1NWUwYmJhZTAxNDA2MTUyNDJiNjM0NjVjMjQxNjQwNDhjYmQ4YmQzMWVlZjQ2NDM0NjBjZjZiOGNmNGFjYQ
相同,只是结尾缺少==符号,但我认为这是一种安慰。我无法想象这是个问题,没有它们,它甚至不是有效的base64字符串长度


那么,为什么digest方法在使用十六进制时输出正确的结果,而在使用二进制时输出错误的答案呢?二进制文件是否与PHP等效文件的“原始”输出不完全相同?如果是这种情况,那么正确的调用方法是什么?

事实上,
摘要
没有问题,
b64url.decode
的结果默认为
utf8
编码(可以通过第二个参数指定),如果您使用:

var sig = b64url.decode(signedRequest[0], 'binary');
var expected = crypto.createHmac('sha256', 'secret').update(signedRequest[1]).digest();
// sig === expected
签名和摘要结果将是相同的

您也可以通过将
摘要
结果转换为
utf8
编码字符串来检查这一点:

var sig = b64url.decode(signedRequest[0]);
var expected = crypto.createHmac('sha256', 'secret').update(signedRequest[1]).digest();
var expected_buffer = new Buffer(expected_sig.digest(), 'binary');
// sig === expected_buffer.toString()

也可以考虑使用现有的库来完成这类工作(可能更多),举几个例子:


我们发现这确实是加密库中的一个bug,并且是github上记录的一个已知问题。我们必须升级并获得修复。

我是Tesserex的合作伙伴。我相信答案可能是Tesserex自传的答案和有趣的编剧的答案的结合。我们仍然在使用Node-ver。0.4.7. 此处可以找到提到的bug Tesserex:。我不完全确定这个bug是否影响了我们,但这似乎是一个很好的可能性。我们将节点更新为0.6.5版,并应用了Jucky Scripter的解决方案,现在一切正常。多谢各位


作为关于使用现有图书馆的建议的说明。大多数现有库都需要express,这是我们试图避免对应用程序的某些细节执行的操作。另外,现有的库倾向于假设您使用node.js就像使用web服务器一样,并且一次只回答一个用户请求。我们正在使用WebSocket的持久连接,我们的facebook客户端将同时处理多个用户的会话数据。最终,我希望我们的Facebook客户端能够开源,用于像我们这样的应用程序。

刚刚检查过,我提供的代码非常适合。。。