如何在Python中生成二进制HMAC并转Base64?Bash转Python求助
问题:Bash转Python代码的HMAC实现与requests auth对应疑问
我需要把以下Bash代码转换为Python代码:
#!/bin/bash username="USERNAME" apiKey='KEY' date=`env LANG="en_US.UTF-8" date -u "+%a, %d %b %Y %H:%M:%S GMT"` password=`echo -n "$date" | openssl dgst -sha1 -hmac $apiKey -binary | openssl enc -base64` curl -i --url "YOUR API HERE" \ -X "POST" \ -H "Date:$date" \ -H "Content-Type: application/json" \ -u "$username:$password" \ -d'{ "urls": [ "YOUR URL HERE" ] }'
目前已经完成大部分改写,但在实现password=echo -n "$date" | openssl dgst -sha1 -hmac $apiKey -binary | openssl enc -base64`这一行功能时遇到困难,当前Python代码如下:
import time import requests import base64 username = "Username" apiKey = 'KEY' date = time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime()) hmac1 = hmac.new(key=apiKey.encode(), msg=date.encode(), digestmod="sha1") message_digest1 = hmac1.hexdigest() headers = { "Date": date, "Content-Type": "application/json" } data = { "urls": [ "YOUR URL HERE" ] } url = 'YOUR API HERE' response = requests.post(url, headers=headers, data=data, auth = (username, message_digest1)) print(response.headers) print(response.text)
已知需要使用hmac和hashlib库,但尝试的方法均无效。另外,curl中的-u参数是否对应Python requests库的auth参数?
解答
1. 修复HMAC-SHA1并Base64编码的问题
核心问题在于:Bash命令是先获取HMAC-SHA1的二进制结果,再进行Base64编码;而你当前用hexdigest()得到的是十六进制字符串,和Bash输出完全不一致。正确步骤:
- 使用
hmac.digest()获取二进制摘要 - 对二进制结果做Base64编码,再转成字符串
- 需额外导入
hmac库
2. curl的-u与requests的auth对应关系
是的,curl的-u username:password就是HTTP基本认证(Basic Authentication),完全对应requests库的auth=(username, password)参数,这部分你的理解正确。
修正后的完整Python代码
import time import requests import base64 import hmac username = "Username" apiKey = 'KEY' # 确保日期格式与Bash一致,避免星期/月份的本地化问题 date = time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime()) # 生成HMAC-SHA1二进制摘要,再Base64编码 hmac_obj = hmac.new(key=apiKey.encode('utf-8'), msg=date.encode('utf-8'), digestmod='sha1') binary_digest = hmac_obj.digest() password = base64.b64encode(binary_digest).decode('utf-8') headers = { "Date": date, "Content-Type": "application/json" } data = { "urls": [ "YOUR URL HERE" ] } url = 'YOUR API HERE' # 使用auth参数做Basic认证,对应curl的-u response = requests.post(url, headers=headers, json=data, auth=(username, password)) print(response.headers) print(response.text)
额外提示:requests.post中如果传入data=data会把字典转成表单格式,而Bash代码是发送JSON数据,所以应该用json=data参数(requests会自动处理Content-Type,手动设置的header也可保留)。
内容的提问来源于stack exchange,提问作者IBAD UR RAHMAN SYED MOHAMMAD
相关产品推荐
相关产品推荐

