I have an RSA public key modulus and exponent string.
I want to create a OpenSSL::PKey::RSA from these two strings.
Basically they come in as:
How would I do this in Ruby? The end goal is to get this to the JWT gem.
I'm currently in Ruby 2.3.1, so this works:
key = OpenSSL::PKey::RSA.new
key.e = OpenSSL::BN.new(Base64.decode64(e), 2)
key.n = OpenSSL::BN.new(Base64.decode64(n), 2)
However, it won't work during an upgrade.
I got it working this way, based on this python implementation:
https://github.com/jpf/okta-jwks-to-pem/blob/master/jwks_to_pem.py
    key = OpenSSL::PKey::RSA.new
    exponent = kid_header['e']
    modulus = kid_header['n']
    # Voila !
    key.set_key(base64_to_long(modulus), base64_to_long(exponent), nil)
    def base64_to_long(data)
      decoded_with_padding = Base64.urlsafe_decode64(data) + Base64.decode64('==')
      decoded_with_padding.to_s.unpack('C*').map do |byte|
        to_hex(byte)
      end.join.to_i(16)
    end
    def to_hex(int)
      int < 16 ? '0' + int.to_s(16) : int.to_s(16)
    end
                        For Ruby 2.4+ you should use :
key = OpenSSL::PKey::RSA.new
key.set_key(n, e, d)
if you do not have d you can set it to nil.
You can use JSON::JWT gem (https://rubygems.org/gems/json-jwt, https://github.com/nov/json-jwt)
# can be found somewhere in `.well-known` space on the server
key_hash = {
  "kty": "RSA",
  "use": "sig",
  "kid": ...,
  "e": ...,
  "n": ...,
  "alg": "RS256"
}
jwk = JSON::JWK.new(key_hash)
JSON::JWT.decode token, jwk.to_key
# voila!
The same can be achieved with Ruby JWT (https://rubygems.org/gems/jwt, https://github.com/jwt/ruby-jwt/blob/master/lib/jwt/jwk/rsa.rb)
public_key = JWT::JWK::RSA.import(key_hash).public_key
JWT.decode token, public_key, true, { algorithm: key_hash[:alg] }
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With