HM1 HM1 - 3 months ago 35
Ruby Question

How to create OpenSSL::PKey using a public key string?

How do I create an

OpenSSL::PKey
object initialized with the following public key string? End goal is to use the object to decode a JWT token using
ruby-jwt
.

I've tried the following:

public_key = ""-----BEGIN CERTIFICATE-----\n ...many characters... \n-----END CERTIFICATE-----\n" # I only have the public key

OpenSSL::PKey.read(key) # Gives ArgumentError: Could not parse PKey: no start line
OpenSSL::PKey.read(key.gsub("CERTIFICATE", "PUBLIC KEY")) # Gives ArgumentError: Could not parse PKey: ASN1 lib


Ultimate goal is to use it decoding JWT:

# example from docs
require 'jwt'

rsa_public => OpenSSL::PKey.read(File.read(File.join(CERT_PATH, 'rsa-2048-public.pem')))
JWT.decode(token, rsa_public, true, { algorithm: "RS256", verify_iat: true })


Any ideas for initializing
OpenSSL::PKey
with public key string?

Answer

As mentioned in the comments, you don't have a RSA public key directly, but a RSA certificate instead, which contains a public key, and it's pretty easy to extract:

require 'openssl'
require 'jwt'

cert = "-----BEGIN CERTIFICATE-----\n .... \n-----END CERTIFICATE-----"
x509 = OpenSSL::X509::Certificate.new(cert)

payload = JWT.decode(token, x509.public_key, true, { algorithm: "RS256", verify_iat: true })

Of course, this will only work if the token was signed with that certificate's corresponding private key. I.e. for a token created like this:

payload = { data: 'test' }

priv = "-----BEGIN RSA PRIVATE KEY----- .....-----END RSA PRIVATE KEY-----"
rsa_private = OpenSSL::PKey::RSA.new(priv)
token = JWT.encode payload, rsa_private, 'RS256'
Comments