Python cryptographyPython cryptography 库
错误信息
Valid PEM but no BEGIN PUBLIC KEY/END PUBLIC KEY delimiters. Are you sure this is a public key?
Python cryptography — ValueError from load_pem_public_key
含义
文件是格式正确的 PEM——封装结构能够解析——但标签不是 PUBLIC KEY。你传给 load_pem_public_key 的是私钥、证书或 CSR。库其实是在直白地问你:是否为这个对象选对了加载函数。
原因
把私钥传给了公钥加载函数
常见BEGIN PRIVATE KEY / BEGIN EC PRIVATE KEY 块需要用 load_pem_private_key 加载。一个配置项(“密钥”)被几条代码路径共用,而这些路径实际需要的是密钥对中的不同部分——这种情况下就常常出现这个错误。
需要裸密钥的地方给了证书
常见BEGIN CERTIFICATE 在 X.509 结构中包含一个公钥。必须先把它作为证书加载,再提取密钥——PEM 标签会告诉你这个对象该由哪个解析器处理。
少见但合法的标签
罕见BEGIN CERTIFICATE REQUEST(CSR)这类对象,或者粘贴进 .pem 文件的 OpenSSH 格式密钥,同样无法通过这项检查——它们各有自己的加载函数,或者需要先转换。
修复方法
- 1.
从你实际拥有的对象推导出公钥
凡是包含密钥材料的容器,只需再多调用一次就能得到公钥。
python from cryptography.hazmat.primitives.serialization import ( load_pem_private_key, load_pem_public_key) from cryptography.x509 import load_pem_x509_certificate first = pem.splitlines()[0] if b"PRIVATE KEY" in first: public_key = load_pem_private_key(pem, password=None).public_key() elif b"CERTIFICATE" in first: public_key = load_pem_x509_certificate(pem).public_key() else: public_key = load_pem_public_key(pem) - 2.
一次性导出规范的 SPKI
如果系统需要反复使用裸公钥,就生成规范的 BEGIN PUBLIC KEY 文件并保存它。
bash openssl pkey -in private.pem -pubout -out public.pem # from a private key openssl x509 -in cert.pem -pubkey -noout > public.pem # from a certificate - 3.
按内容给文件命名
这类失败有一半是文件管理错误,而不是代码错误:server.pem 里把密钥、证书和证书链拼在了一起,或者 public.pem 是复制了错误命令的输出得到的。每个文件只存放一个对象,并在文件名中写明对象类型(orders-es256-public.pem),这一整类加载函数不匹配的问题就会从代码库中消失。