エラーメッセージ
Incorrect password, could not decrypt key
別の表記
- ValueError: Incorrect password, could not decrypt key
- Bad decrypt. Incorrect password?
リリースごとの表記(それぞれ確認済み):45.0 以降は「Incorrect password, could not decrypt key」、43〜44 はパスワードの誤りを「Could not deserialize key data… the provided password may be incorrect…」として報告し、42 以前は「Bad decrypt. Incorrect password?」です。
Python cryptography — ValueError from load_pem_private_key / load_der_private_key / pkcs12.load_key_and_certificates
このエラーの意味
鍵は暗号化されており、cryptography は指定されたパスワードで復号を試みましたが、失敗しました。暗号化された秘密鍵には「パスワードのヒント」はなく、唯一の手がかりは復号したバイト列が有効な鍵にならないことだけです。そのため、このエラーは常に、渡したバイト列が暗号化時に使われたパスフレーズではないことを意味します。
発生する理由
末尾の改行がパスワードに含まれている
よくある`echo secret > file` で保存したパスフレーズ、ファイルから作成した Kubernetes のシークレット、`.env` ファイル内のパスフレーズは、末尾が `\n` になっていることがよくあります。ファイルをそのまま読み込むと、1 バイト多く渡されます。
パスフレーズが別の鍵のものである
よくある1 つのシークレットストアに複数の鍵と複数のパスフレーズがある場合や、ローテーション中に鍵が暗号化し直されたのに、アプリケーションが古いパスフレーズを使い続けている場合です。
非 ASCII のパスフレーズが異なる方法でエンコードされている
ときどき鍵を暗号化したツールは、非 ASCII 文字を含むパスフレーズに Latin-1 や UTF-16 を使った可能性がありますが、コードは UTF-8 でエンコードしています。文字は一致していても、バイト列は一致しません。
古いツールで作成された PKCS#12 ファイル
ときどき一部の古い `.p12` エクスポートでは、空のパスワードの扱いが異なります(パスワードなしか、空文字列か)。ほかの値を当て推量で試すのではなく、`None` と `b""` を意識的に試してください。
修正方法
- 1.
パスフレーズをバイト単位で正確に読み込む
取り除くのは改行コードだけにし、ほかの空白文字は決して取り除かないでください。また、パスフレーズは読み込み元からローダーまでバイト列のまま扱ってください。
python from pathlib import Path passphrase = Path("/run/secrets/key_passphrase").read_bytes().rstrip(b"\r\n") key = serialization.load_pem_private_key(pem, password=passphrase) - 2.
コードの外でパスフレーズを確認する
手で入力したパスフレーズを OpenSSL が受け入れるのにコードでは失敗する場合、違いはコードでの読み込み方(改行、文字コード)にあります。OpenSSL でも失敗する場合は、単にパスフレーズが間違っています。
bash # Prompts for the passphrase; "bad decrypt" means the passphrase is wrong, not the file openssl pkey -in encrypted.pem -noout && echo "passphrase OK" printf '%s' "$KEY_PASSPHRASE" | wc -c # length without a trailing newline