import json
import base64, time, os, struct, secrets, hashlib
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from Conf.golob import mchid, serial_no, appId
def generate_signature(payload):
url_path = "/v3/pay/transactions/jsapi"
timestamp = f"{int(time.time())}"
nonce_str = secrets.token_hex(16).upper()
json_payload = json.dumps(payload, ensure_ascii=False, indent=2)
sign_string = r'POST\n{}\n{}\n{}\n{}\n'.format(url_path, timestamp, nonce_str, json_payload)
print(sign_string)
with open("apiclient_key.pem", "rb") as key_file:
private_key = serialization.load_pem_private_key(
key_file.read(),
password=None,
backend=default_backend()
)
digest = hashlib.sha256(sign_string.encode()).digest()
signature = private_key.sign(
digest,
padding.PKCS1v15(),
hashes.SHA256()
)
base64_signature = base64.b64encode(signature).decode('utf-8')
rep_header = {
"Authorization": f'WECHATPAY2-SHA256-RSA2048 mchid="{mchid}",nonce_str="{nonce_str}",signature="{base64_signature}",timestamp="{timestamp}",serial_no="{serial_no}"',
'Accept': "application/json",
"Content-Type": "application/json"
}
return rep_header
if __name__ == '__main__':
generate_signature()
这块签名有问题吗
你需要直接对签名字符串进行签名,而不是对哈希值进行签名
with open("apiclient_key.pem", "rb") as key_file:
private_key = serialization.load_pem_private_key(
key_file.read(),
password=None,
backend=default_backend()
)
# # Create a SHA-256 hash of the data
# digest = hashlib.sha256(sign_string.encode()).digest()
# 直接对签名字符串进行签名
signature = private_key.sign(
sign_string.encode(),
padding.PKCS1v15(),
hashes.SHA256()
)
# 对签名结果进行 base64 编码
base64_signature = base64.b64encode(signature).decode('utf-8')
是这样嘛
import base64, time, os, struct, secrets, hashlib
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from Conf.golob import mchid, serial_no, appId
def generate_signature(payload):
# 请求参数
url_path = "/v3/pay/transactions/jsapi"
timestamp = f"{int(time.time())}"
nonce_str = secrets.token_hex(16).upper()
# 转换 payload 为 JSON 字符串,保持中文字符
json_payload = json.dumps(payload, ensure_ascii=False)
# 构造待签名字符串
sign_string = 'POST\n{}\n{}\n{}\n{}\n'.format(url_path, timestamp, nonce_str, json_payload)
print(sign_string)
# 读取私钥
with open("apiclient_key.pem", "rb") as key_file:
private_key = serialization.load_pem_private_key(
key_file.read(),
password=None,
backend=default_backend()
)
# 使用 SHA256 with RSA 对签名字符串进行签名
signature = private_key.sign(
sign_string.encode(), # 待签名字符串转为字节格式
padding.PKCS1v15(),
hashes.SHA256() # 指定 SHA256 哈希算法
)
# 对签名结果进行 base64 编码
base64_signature = base64.b64encode(signature).decode('UTF-8')
rep_header = {
"Authorization": f'WECHATPAY2-SHA256-RSA2048 mchid="{mchid}",nonce_str="{nonce_str}",signature="{base64_signature}",timestamp="{timestamp}",serial_no="{serial_no}"',
'Accept': "application/json",
"Content-Type": "application/json"
}
print(rep_header)
return rep_header
改成这样后 还是报签名错误,请检查后再试