Mensaje de error
Could not parse PKey (OpenSSL::PKey::PKeyError)
También se muestra como
- OpenSSL::PKey::PKeyError: Could not parse PKey
- Neither PUB key nor PRIV key (OpenSSL::PKey::RSAError)
- invalid curve name (OpenSSL::PKey::ECError)
Si no se captura, Ruby imprime «…: Could not parse PKey (OpenSSL::PKey::PKeyError)». Los constructores específicos de cada clase lanzan `OpenSSL::PKey::RSAError` / `ECError` con sus propios textos.
Ruby openssl gem — OpenSSL::PKey.read / OpenSSL::PKey::RSA.new / OpenSSL::PKey::EC.new
Qué significa
`OpenSSL::PKey.read` probó todos los formatos de clave que conoce OpenSSL (PEM y DER, públicas y privadas, cifradas con la contraseña indicada) y ninguno funcionó. Ruby no transmite el motivo concreto de OpenSSL, así que el mismo texto cubre un PEM estropeado, una frase de contraseña incorrecta y datos que ni siquiera son una clave. Los constructores específicos de cada algoritmo fallan de forma parecida: `RSA.new` con «Neither PUB key nor PRIV key» y `EC.new` con «invalid curve name» (trata la entrada que no puede analizar como un nombre de curva).
Por qué ocurre
Saltos de línea sustituidos por \n literales
frecuenteLas claves de varias líneas en variables de entorno, variables de configuración de Heroku/Render o cadenas YAML suelen acabar en una sola línea con secuencias `\n`.
Clave cifrada sin contraseña o con una contraseña incorrecta
frecuente`PKey.read(data)` sin el segundo argumento no puede descifrar una clave cifrada; una contraseña incorrecta produce el mismo error, no uno específico de la contraseña.
No es una clave que OpenSSL pueda leer
ocasionalUna clave pública OpenSSH (`ssh-ed25519 AAAA…`), un documento JSON de JWK o un archivo de cadena de certificados con texto adicional antes del bloque PEM.
Cómo solucionarlo
- 1.
Restaurar los saltos de línea y comprobar la clave cargada
Vuelve a convertir las secuencias `\n` en saltos de línea, lee la clave una sola vez al arrancar y comprueba su tipo y si es 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.
Guardar las claves de varias líneas donde se conserven intactas
Las credenciales cifradas de Rails o un archivo de secreto montado conservan el PEM exactamente, a diferencia de las variables de entorno de una sola línea.
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))