本文へスキップ
ecdsa.com
Ruby openssl gemRuby

エラーメッセージ

Could not parse PKey (OpenSSL::PKey::PKeyError)

別の表記

  • OpenSSL::PKey::PKeyError: Could not parse PKey
  • Neither PUB key nor PRIV key (OpenSSL::PKey::RSAError)
  • invalid curve name (OpenSSL::PKey::ECError)

捕捉されない場合、Ruby は「…: Could not parse PKey (OpenSSL::PKey::PKeyError)」と出力します。クラス固有のコンストラクターは、それぞれ独自のテキストで `OpenSSL::PKey::RSAError` / `ECError` を発生させます。

Ruby openssl gem — OpenSSL::PKey.read / OpenSSL::PKey::RSA.new / OpenSSL::PKey::EC.new

このエラーの意味

`OpenSSL::PKey.read` は、OpenSSL が知っているすべての鍵形式(PEM と DER、公開鍵と秘密鍵、渡されたパスワードで暗号化されたもの)を試しましたが、どれも成功しませんでした。Ruby は OpenSSL の具体的な理由を伝えないため、壊れた PEM、誤ったパスフレーズ、そもそも鍵ではないデータのいずれでも同じテキストになります。アルゴリズム固有のコンストラクターも同様に失敗し、`RSA.new` は「Neither PUB key nor PRIV key」で、`EC.new` は「invalid curve name」で失敗します(解析できない入力を曲線名として扱うためです)。

発生する理由

修正方法

  1. 1.

    改行を復元し、読み込んだ内容を確認する

    `\n` シーケンスを改行に戻し、鍵は起動時に一度だけ読み込んで、その種類と秘密鍵かどうかをアサートしてください。

    ruby
    pem = ENV.fetch("JWT_PUBLIC_KEY").gsub("\\n", "\n")   # restore real newlines
    key = OpenSSL::PKey.read(pem)
    raise "expected a public EC key" if key.private? || !key.is_a?(OpenSSL::PKey::EC)
  2. 2.

    複数行の鍵を、壊れずに保たれる場所に保存する

    1 行の環境変数とは異なり、Rails の暗号化された認証情報(credentials)やマウントしたシークレットファイルは、PEM をそのまま保持します。

    ruby
    # Rails: keep multi-line keys in encrypted credentials instead of ENV
    # bin/rails credentials:edit
    #   jwt:
    #     public_key: |
    #       -----BEGIN PUBLIC KEY-----
    #       ...
    key = OpenSSL::PKey.read(Rails.application.credentials.dig(:jwt, :public_key))

関連するエラー

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