class OpenSSL::PKey::RSA
Constants
- CALG_RSA_KEYX
- PRIVATEKEYBLOB
- PUBLICKEYBLOB
- RSA1
- RSA2
Public Class Methods
from_mskeyblob(key)
click to toggle source
# File lib/mskeyblob.rb, line 14 def self.from_mskeyblob(key) b_type, b_version, reserved, alg_id, # PUBLICKEYSTRUC magic, bit_len, public_exponent, # RSAPUBKEY rest = key.unpack('CCSL LLL a*') # PUBLICKEYBLOB || PRIVATEKEYBLOB raise OpenSSL::PKey::RSAError, "Neither PUB key nor PRIV key: invalid bType #{b_type}" unless [PUBLICKEYBLOB, 0x7].include? b_type raise OpenSSL::PKey::RSAError, "Neither PUB key nor PRIV key: invalid bVersion #{b_version}" unless b_version == 2 raise OpenSSL::PKey::RSAError, "Neither PUB key nor PRIV key: invalid magic #{magic}" unless [RSA1, RSA2].include? magic b8 = "a#{bit_len / 8}" b16 = "a#{bit_len / 16}" unpack_pattern = [b8, b16, b16, b16, b16, b16, b8].join('') modulus, p1, p2, e1, e2, c, private_exponent = rest.unpack(unpack_pattern) modulus, p1, p2, e1, e2, c, private_exponent = [modulus, p1, p2, e1, e2, c, private_exponent].map do |byte_array| if byte_array.empty? nil else OpenSSL::BN.new byte_array.reverse, 2 end end key = OpenSSL::PKey::RSA.new key.n = modulus key.e = public_exponent if private_exponent key.d = private_exponent key.p = p1 key.q = p2 key.dmp1 = e1 key.dmq1 = e2 key.iqmp = c end key end
Public Instance Methods
to_mskeyblob(include_private: :not_set)
click to toggle source
# File lib/mskeyblob.rb, line 56 def to_mskeyblob(include_private: :not_set) if include_private == :not_set include_private = private? else if include_private && !private? raise OpenSSL::PKey::RSAError, 'Public key can not export private part' end end b_type = include_private ? PRIVATEKEYBLOB : PUBLICKEYBLOB b_version = 2 reserved = 0 alg_id = CALG_RSA_KEYX magic = include_private ? RSA2 : RSA1 bit_len = n.num_bits # https://github.com/ruby/openssl/issues/5 public_exponent = e b8 = "a#{bit_len / 8}" b16 = "a#{bit_len / 16}" header = [ b_type, b_version, reserved, alg_id, # PUBLICKEYSTRUC magic, bit_len, public_exponent, # RSAPUBKEY ].pack('CCSL LLL') modulus, p1, p2, e1, e2, c, private_exponent = [n, p, q, dmp1, dmq1, iqmp, d].map do |bn| if bn bn.to_s(2).reverse else nil end end if include_private pack_pattern = [b8, b16, b16, b16, b16, b16, b8].join('') header + [modulus, p1, p2, e1, e2, c, private_exponent].pack(pack_pattern) else header + [modulus].pack(b8) end end