簡體   English   中英

Python HMAC 到 CryptoJS

[英]Python HMAC to CryptoJS

我的問題與Translation from Python to JavaScript: HMAC-SHA256非常相似,但該問題從未得到解答。

以下 Python 代碼生成正確的哈希值:

def sign_api_request(api_secret, api_key, method, url):
    encoded_url = urllib.parse.quote(url.lower(), '').lower()
    timestamp = int(time.time())print("timestamp: " + str(timestamp))
    nonce = str(uuid.uuid4())

    signature = api_key + method + encoded_url + str(timestamp) + nonce

    secret_bytes = base64.b64decode(api_secret)

    signature_bytes = signature.encode('UTF8')

    signature_hash = hmac.new(secret_bytes, signature_bytes, hashlib.sha256).digest()
    base64_signature_hash = base64.b64encode(signature_hash).decode()

    print(base64_signature_hash)

我正在嘗試使用 Javascript 生成相同的哈希字符串(作為 Postman 預請求腳本)。 這是我所擁有的:

function epochTime() {
    var d = new Date();
    var t = d.getTime();
    var o = t + "";
    return o.substring(0, 10);
}

function newGuid() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : r & 0x3 | 0x8; return v.toString(16); });
}

var uri_path = encodeURIComponent(request.url.toLowerCase()).toLowerCase();
var payload = uri_path; //.toLowerCase();

timestamp = epochTime();
nonce = newGuid();
signature = environment.api_key + "GET" + payload + timestamp + nonce;

secret_bytes = atob(environment.api_secret);

var hash = CryptoJS.HmacSHA256(signature, secret_bytes);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var sig = "amx " + environment.api_key + ":" + hashInBase64 + ":" + nonce + ":" + timestamp;
postman.setGlobalVariable("signature", sig);

如果我使用相同的timestampnonce (通過顯式設置它們而不是在運行時生成它們)和相同的api_keyapi_secret (它們在調用中保持不變)我希望在sig (Javascript) 中獲得與在base64_signature_hash相同的值(Python),但事實並非如此。

我知道這可能是編碼問題,但我的 js-fu 很弱。 有什么想法嗎?

編輯添加:每個使用的methodurl也相同。

基本上,有兩個問題。 首先,在 Python 和 JS 代碼中, secret_bytes應該是 base64 編碼的字符串。 其次,在 JavaScript 代碼中, secret_bytes沒有從 base64 字符串正確解碼。 請在下面找到更正的 Python 和 JavaScript 示例。

蟒蛇:

import hmac
import time
import uuid
import base64
import hashlib
import urllib.parse


def sign_api_request(api_secret, api_key, method, url):
    encoded_url = urllib.parse.quote(url.lower(), '').lower()
    # timestamp = int(time.time())
    # nonce = str(uuid.uuid4())
    timestamp = str(1569158586);
    nonce = '708b7df1-7494-49fa-812c-e5f6c24aeab6'

    signature = api_key + method + encoded_url + timestamp + nonce
    # print(signature)

    secret_bytes = base64.standard_b64decode(api_secret)
    # print(secret_bytes)

    signature_bytes = signature.encode('UTF8')

    signature_hash = hmac.new(secret_bytes, signature_bytes, hashlib.sha256).digest()
    base64_signature_hash = base64.b64encode(signature_hash).decode()
    return base64_signature_hash 


base64_signature_hash = sign_api_request('MTIzNDU2NzgxMjM0NTY3ODEyMzQ1Njc4MTIzNDU2Nzg=', '0987654321', 'POST', '/signin')
print(base64_signature_hash)

JavaScript:

const CryptoJS = require('crypto-js');

function epochTime() {
    var d = new Date();
    var t = d.getTime();
    var o = t + "";
    return o.substring(0, 10);
}

function newGuid() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : r & 0x3 | 0x8; return v.toString(16); });
}

let api_secret = 'MTIzNDU2NzgxMjM0NTY3ODEyMzQ1Njc4MTIzNDU2Nzg=';
let api_key = '0987654321';
let method = 'POST';
let url_path = '/signin';

let encoded_url = encodeURIComponent(url_path.toLowerCase()).toLowerCase();
let timestamp = '1569158586';
let nonce = '708b7df1-7494-49fa-812c-e5f6c24aeab6';

let signature = api_key + method + encoded_url + timestamp + nonce;
// console.log(signature);

let secret_bytes = new Buffer.from(api_secret, 'base64');
secret_bytes = secret_bytes.toString('ascii');
// console.log(secret_bytes);

let hash = CryptoJS.HmacSHA256(signature, secret_bytes);
let hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
console.log(hashInBase64);

兩者的輸出應該相同:

1Hw92JPDJPFB3Je4MvwapODmn5S6KdIbvot3MAvg0jM=

這是一個很好的python到javascript的翻譯

蟒蛇簽名API請求

import hmac
import base64
import hashlib

SECRET_KEY = 'b7566b7c87365a970e64109f92bb7415719cca1a0fea04c196f7ca7a45cc64b4'
API_KEY = '/v1/users/me'

def sign_api_request(api_secret=SECRET_KEY, api_key=API_KEY):

    signature_hash = hmac.new(api_secret.encode(), api_key.encode(),  hashlib.sha512).digest()
    base64_signature_hash = base64.b64encode(signature_hash).decode()

    return base64_signature_hash

等於nodejs sign-api-request

const CryptoJS = require('crypto-js');


SECRET_KEY = 'b7566b7c87365a970e64109f92bb7415719cca1a0fea04c196f7ca7a45cc64b4'
API_KEY = '/v1/users/me'

function sign_api_request(api_secret=SECRET_KEY, api_key=API_KEY) {
   return CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA512(api_key, api_secret));
}

console.log(sign_api_request())


npm 安裝加密js

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM