向Python服务端发公钥时调用load_pem_public_key遇反序列化错误
解决cryptography库load_pem_public_key加载公钥失败的问题
我之前在Python3.5环境里用cryptography加载PEM公钥时也踩过类似的坑,结合实际经验给你几个排查和解决的方向:
1. 先检查PEM公钥的格式是否标准
这是最常见的问题,load_pem_public_key对PEM格式的要求很严格,必须包含完整的首尾标记,而且中间的Base64内容不能有多余空格、换行错误或者损坏。
正确的PEM公钥格式应该是这样的:
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxQ8zL...(这里是连续的Base64字符,每行约64个) ... -----END PUBLIC KEY-----
你可以先打印出你的pem_data,看看是否符合这个格式:
- 有没有漏掉开头或结尾的
-----BEGIN PUBLIC KEY-----/-----END PUBLIC KEY-----? - 中间的密钥内容是不是被挤成了一行,或者有莫名其妙的空格?
如果是从前端或者网络请求里拿到的公钥,很可能因为传输过程中丢失了换行符,这时候可以用代码处理补全:
# 假设pem_data是没有换行的纯Base64字符串,手动补全格式 pem_data = "-----BEGIN PUBLIC KEY-----" + "\n" + pem_data + "\n" + "-----END PUBLIC KEY-----"
2. 检查Python和cryptography的版本兼容性
你用的是Python3.5,这个版本已经停止维护了,而cryptography的3.0及以上版本已经不再支持Python3.5。如果你的cryptography版本太高,就会出现各种奇怪的后端适配报错。
解决方法是安装适配Python3.5的稳定版本,比如2.9.2:
pip uninstall cryptography pip install cryptography==2.9.2
3. 验证公钥本身是否有效
有时候公钥本身就是损坏的,你可以用OpenSSL命令行工具快速验证:
# 先把公钥内容保存到文件,比如public_key.pem openssl rsa -pubin -in public_key.pem -text -noout
如果命令执行失败并报错,说明公钥本身有问题,需要重新生成或者从正确渠道获取。
4. 确保传入的是bytes类型数据
load_pem_public_key要求传入的是bytes类型,如果你传入的是字符串,需要先转成bytes:
# 如果pem_data是字符串,转成bytes格式 pem_bytes = pem_data.encode('utf-8') key = serialization.load_pem_public_key(pem_bytes, backend=default_backend())
如果公钥是通过base64编码传输的,还要先解码:
import base64 pem_bytes = base64.b64decode(pem_data_str) key = serialization.load_pem_public_key(pem_bytes, backend=default_backend())
内容的提问来源于stack exchange,提问作者jdtotow




