Mensagem de erro
Could not parse PKey (OpenSSL::PKey::PKeyError)
Também aparece como
- OpenSSL::PKey::PKeyError: Could not parse PKey
- Neither PUB key nor PRIV key (OpenSSL::PKey::RSAError)
- invalid curve name (OpenSSL::PKey::ECError)
Sem tratamento, o Ruby imprime “…: Could not parse PKey (OpenSSL::PKey::PKeyError)”. Os construtores específicos de cada classe lançam `OpenSSL::PKey::RSAError` / `ECError` com textos próprios.
Ruby openssl gem — OpenSSL::PKey.read / OpenSSL::PKey::RSA.new / OpenSSL::PKey::EC.new
O que significa
O `OpenSSL::PKey.read` tentou todos os formatos de chave que o OpenSSL conhece (PEM e DER, pública e privada, criptografada com a senha informada) e nenhum funcionou. O Ruby não repassa o motivo específico do OpenSSL, então o mesmo texto cobre um PEM corrompido, uma frase secreta errada e dados que nem são uma chave. Os construtores específicos de cada algoritmo falham de forma parecida: `RSA.new` com “Neither PUB key nor PRIV key”, `EC.new` com “invalid curve name” (ele trata uma entrada que não consegue analisar como um nome de curva).
Por que acontece
Quebras de linha substituídas por \n literais
comumChaves de várias linhas em variáveis de ambiente, variáveis de configuração do Heroku/Render ou strings YAML muitas vezes acabam em uma única linha com sequências `\n`.
Chave criptografada sem senha ou com a senha errada
comum`PKey.read(data)` sem o segundo argumento não consegue descriptografar uma chave criptografada; uma senha errada produz o mesmo erro, e não um erro específico de senha.
Não é uma chave que o OpenSSL consiga ler
ocasionalUma chave pública OpenSSH (`ssh-ed25519 AAAA…`), um documento JSON de JWK ou um arquivo de cadeia de certificados com texto extra antes do bloco PEM.
Como corrigir
- 1.
Restaurar as quebras de linha e conferir o que foi carregado
Converta as sequências `\n` de volta, leia a chave uma única vez na inicialização e confirme o tipo dela e se ela é privada.
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.
Armazenar chaves de várias linhas onde elas ficam intactas
As credenciais criptografadas do Rails ou um arquivo de segredo montado preservam o PEM exatamente, ao contrário das variáveis de ambiente de uma linha só.
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))