最初目的是验证参数签名。 由于因为 sign 太长,超出了微信 URL Link 的自定义参数长度限制。最终没有采用此算法 sha1 的目的是降低明文长度 """ RSA with SHA1 签名和验证 """ import hashlib import random import string from typing import cast from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import padding, rsa def sha1(data: bytes) -> bytes: return hashlib.sha1(data).digest() def generate_rsa_keys(): private_key = rsa.generate_private_key( public_exponent=65537, key_size=1024, backend=default_backend(), ) public_key = private_key.public_key() private_pem = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption(), ) public_pem = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo, ) return private_pem, public_pem hash_algorithm = hashes.SHA1() def sign_rsa(private_key: bytes, data: bytes): # 加载私钥 pk = cast(rsa.RSAPrivateKey, serialization.load_pem_private_key(private_key, None)) # 对数据进行签名 signature = pk.sign(data, padding.PKCS1v15(), hash_algorithm) return signature def verify_rsa(public_key: bytes, data: bytes, signature: bytes): pk = cast(rsa.RSAPublicKey, serialization.load_pem_public_key(public_key)) try: pk.verify(signature, data, padding.PKCS1v15(), hash_algorithm) return True except Exception: return False def _test_rsa_sign_verify(): private_key, public_key = generate_rsa_keys() print("private_key", private_key) print("public_key", public_key) for _ in range(10): word_len = random.randint(10, 100) word = "".join(random.choices(string.ascii_letters + string.digits, k=word_len)) word_sha1 = sha1(word.encode()) signature = sign_rsa(private_key, word_sha1) signature_hex = signature.hex() raw_signature = bytes.fromhex(signature_hex) print("signature", len(signature_hex), signature_hex) assert verify_rsa(public_key, word_sha1, raw_signature) assert not verify_rsa(public_key, word_sha1 + b"1", raw_signature) print("pass") if __name__ == "__main__": _test_rsa_sign_verify()