Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

ruby

openssl

jwt

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?

like image 674
HM1 Avatar asked Aug 06 '16 00:08

HM1


1 Answers

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'
like image 155
Seba Avatar answered Sep 28 '22 07:09

Seba