エラーメッセージ
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