来自指数和模数字符串的Ruby RSA

时间:2017-09-08 16:53:53

标签: ruby rsa

我有一个RSA公钥模数和指数字符串。

我想从这两个字符串中创建一个OpenSSL::PKey::RSA

基本上他们是:

  • n ='长字符串'
  • e =' 4个字符的字符串'

我如何在Ruby中执行此操作? 最终目标是将其发送到JWT gem。

更新

我目前在Ruby 2.3.1中,所以这有效:

key = OpenSSL::PKey::RSA.new
key.e = OpenSSL::BN.new(Base64.decode64(e), 2)
key.n = OpenSSL::BN.new(Base64.decode64(n), 2)

但是,它在升级过程中不会起作用。

3 个答案:

答案 0 :(得分:2)

我基于以下python实现以这种方式工作:

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

答案 1 :(得分:1)

对于Ruby 2.4+,你应该使用:

key = OpenSSL::PKey::RSA.new
key.set_key(n, e, d)

如果您没有d,可以将其设置为nil

答案 2 :(得分:1)

您可以使用JSON::JWT个gem(https://rubygems.org/gems/json-jwthttps://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!

使用Ruby JWT(https://rubygems.org/gems/jwthttps://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] }