エラーメッセージ
Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).
別の表記
- ValueError: Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters). Details: ASN.1 parsing error: short data (needed at least 48 additional bytes)
- Could not deserialize key data. The data may be in an incorrect format, the provided password may be incorrect, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).
- ValueError: ('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [<OpenSSLError(code=503841036, lib=60, reason=524556, reason_text=unsupported)>
リリースごとに確認した結果:cryptography 45.0 以降は「Details: …」(たとえば「ASN.1 parsing error: short data」)を付け加えます。43〜44 は OpenSSL のエラーオブジェクトを含むタプルとしてこのテキストを送出し、文に「the provided password may be incorrect」を加えます(パスワードが間違っている場合にもこのメッセージを使います)。36〜42 はその文言を含まないタプル形式で送出します。
Python cryptography — ValueError from load_pem_private_key / load_der_private_key / load_der_public_key
このエラーの意味
cryptography は、鍵オブジェクトに変換できない鍵データを見つけました。PEM 入力の場合、アーマー行には問題がありません(問題があれば「Unable to load PEM file」が表示されます)。つまり問題は内部の DER にあり、DER が途中で切れているか、ローダーが想定するものとは別の構造であるか、cryptography が読み込みを拒否する鍵(明示的な曲線パラメーターを持つ EC 鍵や、サポートされていないアルゴリズムで暗号化された鍵)を表しているかのいずれかです。最近のバージョンでは、低レベルの ASN.1 の理由を示す「Details: …」が付け加えられます。
発生する理由
base64 の本体が不完全か改変されている
よくあるターミナルやシークレットマネージャーから鍵をコピーする際に行が抜けた、サイズ制限のある入力欄で鍵が切り詰められた、エディターが文字を変更した、などのケースです。ヘッダーとフッターは残っているため、PEM の解析は成功し、DER の解析が失敗します。
ローダーが鍵の構造と一致していない
よくある`load_der_private_key` に渡された公開鍵、鍵のローダーに渡された証明書、`load_ssh_private_key` ではなく `load_pem_private_key` に渡された OpenSSH 形式の鍵(`-----BEGIN OPENSSH PRIVATE KEY-----`)などが該当します。
明示的な曲線パラメーターを持つ EC 鍵
ときどき一部の古いツールで生成された鍵や HSM からエクスポートされた鍵は、曲線を OID で指定する代わりに、曲線の素数、係数、生成元を明示的に記述しています。cryptography は意図的にこうした鍵を拒否します(RFC 5480 は、PKIX では名前付き曲線を使うことを必須としています)。
cryptography がサポートしていないアルゴリズムで暗号化されている
ときどき従来の PBE 方式(たとえば PBE-SHA1-RC2 や DES 系の方式)で暗号化された PKCS#8 ファイルは、現在のビルドでは復号できません。AES で暗号化し直してください(`openssl pkcs8 -topk8 -v2 aes-256-cbc`)。
修正方法
- 1.
まず OpenSSL で鍵を確認する
`openssl asn1parse` の時点で失敗する場合は、ファイルが破損しています。新しいコピーを入手してください。OpenSSL では読み込めるのに cryptography では読み込めない場合は、曲線のエンコーディングか暗号化アルゴリズムを確認してください。
bash openssl asn1parse -in key.pem | head -20 # does the DER parse at all? openssl pkey -in key.pem -noout -text | head # private key: type, curve, size openssl pkey -pubin -in pub.pem -noout -text # public key - 2.
鍵に合ったローダーを使う
PEM、DER、OpenSSH のどのローダーを使うかはデータそのものから判断し、公開鍵には公開鍵用のローダーを使ってください。
python from cryptography.hazmat.primitives import serialization def load_any_private_key(data: bytes, password: bytes | None = None): if data.lstrip().startswith(b"-----BEGIN OPENSSH PRIVATE KEY-----"): return serialization.load_ssh_private_key(data, password) if data.lstrip().startswith(b"-----BEGIN"): return serialization.load_pem_private_key(data, password) return serialization.load_der_private_key(data, password) - 3.
明示的なパラメーターを名前付き曲線に変換する
OpenSSL 3 はデフォルトで名前付き曲線を使って EC 鍵を書き出すため、鍵を一度エクスポートし直すだけで、明示的なパラメーターを持つ鍵の問題がすべてのライブラリで解消されます。
bash # Re-encode an EC key with a named curve instead of explicit parameters openssl pkey -in explicit.pem -out named.pem openssl ec -in named.pem -param_out -noout -text | grep "ASN1 OID" # e.g. prime256v1
関連するエラー
Unable to load PEM file. See https://cryptography.io/en/latest/faq/#why-can-t-i…Python cryptographyValid PEM but no BEGIN PUBLIC KEY/END PUBLIC KEY delimiters. Are you sure this…Python cryptographyPassword was given but private key is not encrypted.Python cryptographyerror:0680009B:asn1 encoding routines:ASN1_get_object:too longOpenSSL 3.x CLI (asn1parse, d2i loaders)