将Nodejs签名散列函数转换为Python

我试图连接到只有Nodejs文档的API,但是我需要使用Python。

官方文档声明hhtp请求需要像这样签名,只给出这个代码:

var pk = ".... your private key ...."; var data = JSON.strigify( {some JSON object} ); var signature = crypto.createSign('RSA-SHA256').update(data).sign(pk, 'base64'); 

到目前为止,我被封锁在那里:

 from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 from Crypto.Hash import SHA256 import base64 private_key_loc='D:\\api_key' BODY={ some JSON } data=json.dumps(BODY) def sign_data(private_key_loc, data): key = open(private_key_loc, "r").read() rsakey = RSA.importKey(key,passphrase='c9dweQ393Ftg') signer = PKCS1_v1_5.new(rsakey) digest = SHA256.new() digest.update(data.encode()) sign = signer.sign(digest) return base64.b64encode(sign) headers={} headers['X-Signature']=sign_data(private_key_loc, data) response = requests.post(url, headers=headers, data=BODY) 

从本质上讲,我不能让他们的代码在Nodejs上运行; 我不知道,因为私钥格式,我得到错误。 所以我无法真正比​​较我所做的。 然而,我正在用python得到一个禁止的信息。

任何想法?

————————————————– ——————–

编辑1

好的两天后,我是这样的:1 /我设法使用Nodejs生成一个有效的签名:

 const crypto = require('crypto'); const fs = require('fs'); var pk = fs.readFileSync('./id_rsa4.txt').toString(); let sampleRequest = {accessKey: 'TESTKEY',reportDate: '2016-09-27T14:25:54.386Z'}; var data = JSON.stringify(sampleRequest); var signature = crypto.createSign('RSA-SHA256').update(data).sign(pk, 'base64'); 

2 /不可能在Python中重现….更糟糕的是,无论我尝试哈希总是在Nodejs中的大小的一半:

 import hmac import hashlib import base64 import json private_key="""PRIVATE KEY SAME FORMAT BUT WITH LINE BREAKS LIKE \n""" data=json.dumps({"accessKey": "TESTKEY","reportDate": "2016-09-27T14:25:54.386Z"}) dig = hmac.new(private_key, msg=data, digestmod=hashlib.sha256).digest() print base64.b64encode(dig) #not valid dig = hmac.new(private_key, msg=data, digestmod=hashlib.sha256).hexdigest() print base64.b64encode(dig) #not valid either 

这太令人沮丧了,还有什么想法?

你应该可以使用Python标准库来生成哈希签名。 这将用签名密钥对数据进行编码。 根据服务器的不同,您也可能需要在请求中手动设置标题值。

 import hmac import hashlib import base64 import json private_key = '12345' data = json.dumps({'foo': 'bar'}) dig = hmac.new(private_key, msg=data, digestmod=hashlib.sha256).digest() b64data = base64.b64encode(dig) request.post(url, data=b64data) 

好的,终于find了我的错误。

基本上我不知道RSA-SHA256和SHA256之间是有区别的…

这里是一段代码,如果需要的话:

 import base64 from Crypto.Hash import SHA256 from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 def _get_key(PEM_LOCATION): with open(PEM_LOCATION, 'rb') as secret_file: secret=secret_file.read() if (secret.startswith('-----BEGIN RSA PRIVATE KEY-----') or secret.startswith('-----BEGIN PRIVATE KEY-----')): # string with PEM encoded key data k = secret rsa_key = RSA.importKey(k) return PKCS1_v1_5.new(rsa_key) else: return None def get_signature(body): data=json.dumps(body) h=SHA256.new() h.update(data) return PRIVATE_KEY.sign(h) def get_signed_headers(body): sig=get_signature(body) headers={} headers['Content-type']='application/json' headers['X-Signature']=base64.b64encode(sig) return headers