Python cryptographyPython cryptography 库
错误信息
Password was given but private key is not encrypted.
也可能输出为
- TypeError: Password was given but private key is not encrypted.
Python cryptography — TypeError from load_pem_private_key / load_der_private_key
含义
你向密钥加载函数传入了 `password`,但密钥是以未加密形式存储的。cryptography 把这视为编程错误(`TypeError`),而不是忽略这个密码,因为静默接受会掩盖配置漂移——例如有人把密钥解密后以明文保存。它与“Password was not given but private key is encrypted”正好相反。
原因
加密密钥已被替换,密码短语设置却保留了下来
常见密钥在重新导出或重新生成时没有加密,但部署仍在提供旧的密码短语变量。由不同团队执行的轮换常常会留下这种不一致。
传入了空字符串而不是 None
常见`password=b""` 也是密码。把未设置的环境变量读成 `""` 再编码的代码,会为未加密的密钥传入空密码,从而得到这个错误。
转换时去掉了加密
偶见`openssl pkey -in enc.pem -out key.pem`(不带加密算法选项)或新密码短语为空的 `ssh-keygen -p` 会以未加密形式写出密钥,而应用程序仍以为需要解密它。
修复方法
- 1.
对未加密的密钥传入 None
把空的配置值统一转换为 `None`。如果策略要求密钥在存储时必须加密,就把这个错误视为部署了未加密密钥的信号,并改为替换该密钥。
python import os from cryptography.hazmat.primitives import serialization passphrase = os.environ.get("KEY_PASSPHRASE") or None # "" becomes None key = serialization.load_pem_private_key(pem, password=passphrase.encode() if passphrase else None) - 2.
根据 PEM 本身判断是否加密
PKCS#8 加密密钥使用 `ENCRYPTED PRIVATE KEY` 标签;旧式 OpenSSL PEM 密钥带有 `Proc-Type: 4,ENCRYPTED` 头部。据此决定是否要求提供密码短语。
python def is_encrypted_pem(pem: bytes) -> bool: head = pem.lstrip()[:64] return head.startswith(b"-----BEGIN ENCRYPTED PRIVATE KEY-----") or b"Proc-Type: 4,ENCRYPTED" in pem