エラーメッセージ
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」で失敗します(解析できない入力を曲線名として扱うためです)。
発生する理由
改行がリテラルの \n に置き換わっている
よくある環境変数、Heroku/Render の設定変数、YAML の文字列に入れた複数行の鍵は、`\n` シーケンスを含む 1 行になってしまうことがよくあります。
暗号化された鍵のパスワードが未指定、または誤っている
よくある2 番目の引数なしの `PKey.read(data)` では、暗号化された鍵を復号できません。パスワードが誤っている場合も、パスワード固有のエラーではなく同じエラーになります。
OpenSSL が読み込める鍵ではない
ときどきOpenSSH の公開鍵(`ssh-ed25519 AAAA…`)、JWK の JSON ドキュメント、または PEM ブロックの前に余分なテキストがある証明書チェーンのファイルです。
修正方法
- 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.
複数行の鍵を、壊れずに保たれる場所に保存する
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))