Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 正在验证Node.js中的HMAC-SHA256签名_Javascript_Node.js_Validation_Authentication_Hmac - Fatal编程技术网

Javascript 正在验证Node.js中的HMAC-SHA256签名

Javascript 正在验证Node.js中的HMAC-SHA256签名,javascript,node.js,validation,authentication,hmac,Javascript,Node.js,Validation,Authentication,Hmac,我正在尝试使用一个简单的Python客户端对Node.js服务器验证HMAC-SHA256签名,该客户端对Python服务器进行验证。由于某些原因,我无法在节点中正确验证它 ## # client.py ## import json import time from urllib import error from urllib import request import hmac from hashlib import sha256 USER = 'testuser' KEY = 'xxwM

我正在尝试使用一个简单的Python客户端对Node.js服务器验证HMAC-SHA256签名,该客户端对Python服务器进行验证。由于某些原因,我无法在节点中正确验证它

##
# client.py
##
import json
import time
from urllib import error
from urllib import request
import hmac
from hashlib import sha256

USER = 'testuser'
KEY = 'xxwMXEqOGiY2TssVZ9hvOB4x6EVW3RW75hjAKEai4UBlxG0ts8Js8dsWOzDvAVq4'


if __name__ == '__main__':
    now = int(time.time())

    payload = {'firstname': 'john', 'lastname': 'doe'}
    payload_json = json.dumps(payload)
    payload_bytes = bytes(payload_json, 'utf-8')

    sig = hmac.new(bytes(KEY, 'utf-8'), b'', sha256)
    sig.update(bytes(str(now), 'utf-8'))
    sig.update(payload_bytes)
    signature = sig.hexdigest()

    headers = {
        'Authorization': '{}:{}'.format(USER, signature),
        'timestamp': str(now),
        'Content-Type': 'application/json',
    }

    req = request.Request('http://localhost:8080/', payload_bytes, headers, method='POST')
    try:
        with request.urlopen(req) as response:
            response_code, response_reason, r = response.code, response.reason, response.read()
    except error.HTTPError as e:
        response_code, response_reason, r = e.code, e.reason, e

    print('RESPONSE: {} {}\n{}'.format(response_code, response_reason, r))
在Python中,我(成功地)验证请求,如下所示:

##
# snippet from server.py
##
user = {'user': 'testuser', 'secret_key': 'xx...'}  # usually queries the database
if user:
    check_sig = hmac.new(bytes(user['secret_key'], 'utf8'), b'', sha256)
    check_sig.update(bytes(headers['TIMESTAMP'], 'utf-8'))  # timestamp sent in request header
    check_sig.update(data)  # data is binary json-formatted string
    check_signature = check_sig.hexdigest()

    if hmac.compare_digest(check_signature, hmac_hash):  # hmac_hash is user's signature from request
        time_diff = int(time.time()) - int(headers['TIMESTAMP'])
        if 0 <= time_diff <= 30:
            print('kewl!')
            return True
/*
* server.js
*/
var restify = require('restify');
var crypto = require('crypto');
var bufferEq = require('buffer-equal-constant-time');
var _ = require('lodash');
var nconf = require('nconf').file({file: 'config.json'});


var server = restify.createServer();
server.use(restify.acceptParser(server.acceptable));
// server.use(require(path.join(__dirname, 'auth'))());
server.use(restify.dateParser());
server.use(restify.queryParser());
server.use(restify.jsonp());
server.use(restify.gzipResponse());
server.use(restify.bodyParser());
// server.use(restify.requestExpiry());
server.use(restify.throttle({
    burst: 100,
    rate: 50,
    ip: true,
    overrides: {
        '192.168.1.1': {
            rate: 0,        // unlimited
            burst: 0
        }
    }
}));
server.use(restify.conditionalRequest());


server.use(function authenticate(req, res, next) {
    console.log('checking auth...');

    var user = req.headers.authorization.split(':')[0];
    var key = req.headers.authorization.split(':')[1];
    console.log(key);

    var credentials = nconf.get('Security:Users');
    var dbUser = _.filter(credentials, {user: user}).pop();

    var checkSignature = crypto.createHmac('sha256', dbUser.key)
        .update(req.headers.timestamp, 'utf8')
        .update(JSON.stringify(req.body), 'utf8')
        .digest('hex');

    console.log(checkSignature);
    if (!bufferEq(new Buffer(checkSignature), new Buffer(key))) {
        return next(new restify.UnauthorizedError('Authorization error.'));
    }

    return next();
});


function respond(req, res, next) {
    res.send('hello!');
    next();
}

server.get('/', respond);
server.post('/', respond);

server.listen(8080, function() {
    console.log('%s listening at %s', server.name, server.url);
});
…但是比较签名总是失败的


这是在节点中创建HMAC-SHA256签名的正确方法吗?我一直在跟踪,这看起来很简单…

你能发布签名的两个最终结果吗?@GiveMeAllYourCats好吧,因为HMAC是用当前时间戳生成的,所以我可以为你提供一堆SHA256字符串,它们在Python中是相同的,在Node.js中总是不同的:)技术上,在Python中,我收到200个OK响应,在节点401中收到未经授权的响应。如果您认为打印/记录我在请求中收到的其他资料或其他任何东西会有所帮助,我很乐意与您分享,请告诉我您到底需要什么;)好的,我想要输出的原因是编码。你注意到什么奇怪的事情了吗?@GiveMeAllYourCats在Python客户端,我正在发送utf-8,由TestRing编码,在Python服务器中(在我的示例中为
data
)接收完全相同的类型和结构。在节点服务器上,
req.body
作为JS对象接收,我随后将其转换为字符串(
JSON.stringify(req.body)
),甚至强制utf-8编码。我试图更改节点端的
缓冲区
比较,但问题是它总是会失败,因为重新生成的签名与用户发送的签名不同(都是SHA256字符串,但它们只是不匹配:)@GiveMeAllYourCats例如,在上一次运行中,发送的签名客户端是
4f8e40a4bf5eb06565e135ad26d1eb430a215759778fba4ed6a6905b66d307d51
,节点服务器上重新生成的签名客户端是
64fe27f4582a8ad3287f7399ba2ff92d5002dbd5b50c95172ab08c4950a54d0
。。。