将 Nodejs 签名哈希函数转换为 Python
Converting Nodejs signature hashing function to 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 标准库来生成散列签名。这将使用签名密钥对数据进行编码。根据服务器的不同,您可能还必须在请求中手动设置 header 值。
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)
好的,终于找到我的错误了
基本上不知道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
我正在尝试连接到只有 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 标准库来生成散列签名。这将使用签名密钥对数据进行编码。根据服务器的不同,您可能还必须在请求中手动设置 header 值。
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)
好的,终于找到我的错误了
基本上不知道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