Converting Nodejs signature hashing function to Python
<p>I'm trying to connect to an API that only has Nodejs doc, but I need to use Python.</p>

<p>The official doc states the hhtp request need to be signed like this and only gives this code:</p>

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

<p>So far, I am blocked there:</p>

<pre><code>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)
</code></pre>

<p>Esentially, I cannot make their code run on Nodejs; I don't know it and I get error because of the private key format. So I can't really compare what I do. Yet, I'm getting an forbidden message with the python.</p>

<p>Any idea?</p>

<p><strong>----------------------------------------------------------------------</strong></p>

<p><strong>EDIT 1</strong></p>

<p>Ok after two days, here is were I am:
1/ I managed to produce a valid signature with Nodejs using:</p>

<pre><code>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');
</code></pre>

<p>2/ Impossible to reproduce in Python.... Even worse, the whatever i try the hash is always half the size of the one in Nodejs:</p>

<pre><code>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
</code></pre>

<p>This is SO frustrating, any more idea?</p>

<p>You should be able to use the python standard library to generate the hashed signature.  This will encode the data with the signed key.  Depending on the server you may have to manually set header values in your request as well.</p>

<pre><code>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)
</code></pre>

python node.js hash rsa http-signature