本文へスキップ
ecdsa.com
Python cryptographyPython の cryptography

エラーメッセージ

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: …」が付け加えられます。

発生する理由

修正方法

  1. 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. 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. 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

関連するエラー

署名エラーデータベースをすべて見る