[英]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);
如果我使用相同的timestamp
和nonce
(通過顯式設置它們而不是在運行時生成它們)和相同的api_key
和api_secret
(它們在調用中保持不變)我希望在sig
(Javascript) 中獲得與在base64_signature_hash
相同的值(Python),但事實並非如此。
我知道這可能是編碼問題,但我的 js-fu 很弱。 有什么想法嗎?
編輯添加:每個使用的method
和url
也相同。
基本上,有兩個問題。 首先,在 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的翻譯
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
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())
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.