Ruby on Rails中用OpenSSL v3通过模和指数创建RSA密钥失败
在Ruby on Rails中通过模和指数创建OpenSSL::PKey::RSA实例的问题解决
环境版本
ruby 3.2.1 (2023-02-08 revision 31819e82c8) [arm64-darwin22] Rails 7.0.8 OpenSSL 3.1.2 1 Aug 2023
三种尝试的错误分析
第一种尝试
执行代码:
modulus = k['n'] exponent= k['e'] rsa = OpenSSL::PKey::RSA.new rsa.set_key_rsa(k['n'], k['e'], 2)
报错信息:
undefined method `set_key_rsa' for #<OpenSSL::PKey::RSA:0x000000010a1468a0 oid=rsaEncryption>
错误原因:set_key_rsa并非OpenSSL::PKey::RSA的有效方法,属于方法名称误用。
第二种尝试
执行代码:
modulus = k['n'] exponent= k['e'] rsa = OpenSSL::PKey::RSA.new rsa.set_key(k['n'], k['e'], 2)
报错信息:
rsa#set_key= is incompatible with OpenSSL 3.0
错误原因:set_key方法在OpenSSL 3.0及以上版本已被废弃,不再支持调用。
第三种尝试
执行代码:
rsa = OpenSSL::PKey::RSA.new rsa.n = OpenSSL::BN.new(Base64.urlsafe_decode64(k['n']), 2) rsa.e = OpenSSL::BN.new(Base64.urlsafe_decode64(k['e']), 2)
报错信息:
undefined method `n=' for #<OpenSSL::PKey::RSA:0x000000010ab56e08 oid=rsaEncryption>
错误原因:Ruby与OpenSSL 3.x的绑定版本移除了直接修改n、e实例属性的赋值方法,无法通过这种方式设置密钥参数。
正确解决方法
针对OpenSSL 3.x和Ruby 3.2+的版本特性,推荐以下两种有效创建RSA公钥实例的方式:
方式一:哈希参数直接初始化
- 将Base64 URL安全编码的模和指数解码为二进制,转换为
OpenSSL::BN对象; - 用哈希传入
n(模)和e(指数)参数,直接初始化OpenSSL::PKey::RSA实例。
示例代码:
require 'base64' require 'openssl' # 假设k是包含n和e的目标哈希 n_bn = OpenSSL::BN.new(Base64.urlsafe_decode64(k['n']), 2) e_bn = OpenSSL::BN.new(Base64.urlsafe_decode64(k['e']), 2) # 创建RSA实例 rsa = OpenSSL::PKey::RSA.new(n: n_bn, e: e_bn) # 验证实例有效性 puts rsa.public_key.to_pem
方式二:构建DER编码创建实例
通过构建RSA公钥的ASN.1结构,转换为DER编码后初始化实例:
require 'base64' require 'openssl' n_bin = Base64.urlsafe_decode64(k['n']) e_bin = Base64.urlsafe_decode64(k['e']) # 构建RSA公钥的ASN.1序列 pub_key_seq = OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(n_bin, 2)), OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(e_bin, 2)) ]) # 转换为DER编码并创建RSA实例 rsa = OpenSSL::PKey::RSA.new(pub_key_seq.to_der)
内容的提问来源于stack exchange,提问作者dugong
相关产品推荐
相关产品推荐

