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

时间:2016-10-10 16:43:27

标签: python node.js hash rsa http-signature

我正在尝试连接到只有Nodejs doc的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

这令人沮丧,更有想法?

2 个答案:

答案 0 :(得分:2)

您应该能够使用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)

答案 1 :(得分:0)

好的,终于找到了我的错误。

基本上我不知道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