Ruby 来自指数和模数字符串的 RSA
Ruby RSA from exponent and modulus strings
我有一个 RSA public 密钥模数和指数字符串。
我想从这两个字符串创建一个 OpenSSL::PKey::RSA
。
基本上它们是:
- n = 'long string'
- e = '4-character string'
我如何在 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)
但是,它在升级期间不起作用。
对于 Ruby 2.4+ 你应该使用:
key = OpenSSL::PKey::RSA.new
key.set_key(n, e, d)
如果您没有 d
,您可以将其设置为 nil
。
我是这样工作的,基于这个 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
您可以使用 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!
同样可以用 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] }
我有一个 RSA public 密钥模数和指数字符串。
我想从这两个字符串创建一个 OpenSSL::PKey::RSA
。
基本上它们是:
- n = 'long string'
- e = '4-character string'
我如何在 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)
但是,它在升级期间不起作用。
对于 Ruby 2.4+ 你应该使用:
key = OpenSSL::PKey::RSA.new
key.set_key(n, e, d)
如果您没有 d
,您可以将其设置为 nil
。
我是这样工作的,基于这个 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
您可以使用 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!
同样可以用 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] }