Перейти к содержимому
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.

    Храните многострочные ключи там, где они не портятся

    Зашифрованные учётные данные Rails или смонтированный файл секрета сохраняют 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))

Связанные ошибки

Открыть всю базу ошибок подписей