错误信息
Password was not given but private key is encrypted
也存在相反的情况:“Password was given but private key is not encrypted.”——同样的调用,不匹配的方向相反(两者都已在 cryptography 50.0 上复现)。
Python cryptography — TypeError from load_pem_private_key
含义
你对一把已加密的私钥调用了 load_pem_private_key(data, password=None)——它的 PEM 标明了 ENCRYPTED PRIVATE KEY,或者带有 Proc-Type: 4,ENCRYPTED 头部。库能看出加密封装,并拒绝猜测:它需要以 bytes 形式提供的密码短语,或者一把真正未加密的密钥。
原因
密钥生成时设置了密码短语,代码却按无密码处理
常见带 -aes256 的 openssl genpkey/ec、设置了密码短语的 ssh-keygen,或者 CA 签发的证书包,都会产生加密的密钥。为明文密钥编写的部署代码随后传入 password=None,就会卡在这里。
有密码,但传递方式不对
常见空密码等同于没有密码:在环境变量未设置时回退为 b"" 的代码,得到的正是这条消息。该参数必须是 bytes——传入 str 会报错“Cannot convert … instance to a buffer”——而从环境变量读取的密码可能带有末尾换行符,导致解密失败并报错“Incorrect password, could not decrypt key”。
选错了密钥文件
偶见读取的是加密的备份副本(key.pem.enc、带密码短语的 id_ecdsa),而不是有意保持未加密的部署密钥。
修复方法
- 1.
以 bytes 形式提供密码短语
通过机密存储传入密码,并编码为 bytes;为稳妥起见,去掉首尾空白字符。
python import os from cryptography.hazmat.primitives.serialization import load_pem_private_key password = os.environ["KEY_PASSPHRASE"].strip().encode() key = load_pem_private_key(pem_bytes, password=password) - 2.
或者在部署配置阶段一次性解密密钥
如果运行时环境无法管理密码短语,就把未加密的密钥存放在正规的机密管理器中——如果加密密钥的密码就放在同一个 env 文件里,加密起不到任何保护作用。如果密码短语曾经和密钥一起出现在仓库中,就轮换密钥:那时的加密只是摆设。
bash openssl pkey -in encrypted.pem -out plain.pem # (prompts once for the passphrase; protect plain.pem via the secret store)