如何用PEM公证书作密钥在Python中计算HMAC-SHA256(JWT场景)
嘿,我来帮你搞定这个问题!首先得先掰扯清楚一个容易混淆的点:HMAC-SHA256是对称加密算法,它依赖的是一个双方共享的对称密钥;而PEM格式的公证书(比如RSA公钥)属于非对称加密体系的范畴。不过我猜你要么是确实需要用公证书里的内容生成HMAC密钥,要么可能是在JWT场景下搞混了签名算法——毕竟JWT里的RS256才是用公钥验证签名的,而HS256是用对称密钥。我分两种情况给你说明:
情况1:确实要用PEM公钥计算HMAC-SHA256哈希
如果你的业务场景就是需要把公钥作为HMAC的密钥来计算,那可以按以下步骤来实现:
- 读取PEM格式的公钥文件
- 解析公钥并序列化为字节数据
- 用这个字节数据作为HMAC的密钥,计算SHA256哈希
下面是具体的Python代码示例:
import hmac import hashlib from cryptography.hazmat.primitives import serialization from cryptography.hazmat.backends import default_backend def calculate_hmac_sha256_with_pem_key(pem_file_path, target_text): # 读取PEM公钥文件 with open(pem_file_path, "rb") as pem_file: pem_content = pem_file.read() # 解析PEM格式的公钥 public_key = serialization.load_pem_public_key( pem_content, backend=default_backend() ) # 将公钥序列化为字节流(这里用SubjectPublicKeyInfo格式,也可根据需求调整) key_bytes = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ) # 计算HMAC-SHA256哈希 hmac_hash = hmac.new(key_bytes, target_text.encode('utf-8'), hashlib.sha256).digest() # 返回十六进制格式的哈希结果(方便查看和传输) return hmac_hash.hex() # 调用示例 text_to_hash = "你需要计算哈希的目标文本" public_key_path = "./your_public_key.pem" result = calculate_hmac_sha256_with_pem_key(public_key_path, text_to_hash) print(f"HMAC-SHA256计算结果: {result}")
情况2:实际是要验证JWT的RS256签名(更常见的JWT场景)
如果你是在开发JWT功能时,想用公证书验证签名,那其实不该用HMAC——JWT里的RS256算法才是用私钥签名、公钥验证的正确方式。这时候用PyJWT库会更简洁高效,代码示例如下:
首先确保你安装了必要的依赖:
pip install pyjwt cryptography
然后是验证代码:
import jwt def verify_jwt_rs256(token, pem_public_key_path): # 读取PEM公钥 with open(pem_public_key_path, "rb") as key_file: public_key = key_file.read() try: # 解码并验证JWT签名 payload = jwt.decode(token, public_key, algorithms=["RS256"]) return f"验证成功,JWT载荷: {payload}" except jwt.InvalidSignatureError: return "签名验证失败,令牌可能被篡改" except jwt.ExpiredSignatureError: return "令牌已过期" except Exception as e: return f"验证出错: {str(e)}" # 调用示例 your_jwt_token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." public_key_path = "./your_public_key.pem" verification_result = verify_jwt_rs256(your_jwt_token, public_key_path) print(verification_result)
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

