SSH SubjectPublicKeyInfo from module and metric

I am retrieving the module and metric from the public SSH key in order to create the PEM public key. Here is my code:

require "base64"
require "openssl"


def unpacked_byte_array(ssh_type, encoded_key)
  prefix = [7].pack("N") + ssh_type
  decoded = Base64.decode64(encoded_key)

  # Base64 decoding is too permissive, so we should validate if encoding is correct
  unless Base64.encode64(decoded).gsub("\n", "") == encoded_key && decoded.slice!(0, prefix.length) == prefix
    raise PublicKeyError, "validation error"
  end

  data = []
  until decoded.empty?
    front = decoded.slice!(0,4)
    size = front.unpack("N").first
    segment = decoded.slice!(0, size)
    unless front.length == 4 && segment.length == size
      raise PublicKeyError, "byte array too short"
    end
    data << OpenSSL::BN.new(segment, 2)
  end
  return data
end

module OpenSSL
  module PKey
    class RSA
      def self.new_from_parameters(n, e)
        a = self.new   # self.new(64) for ruby < 1.8.2
        a.n = n        # converted to OpenSSL::BN automatically
        a.e = e
        a
      end
    end
  end
end

e, n = unpacked_byte_array('ssh-rsa', 'AAAAB3NzaC1yc2EAAAABIwAAAQEA3RC8whKGFx+b7BMTFtnIWl6t/qyvOvnuqIrMNI9J8+1sEYv8Y/pJRh0vAe2RaSKAgB2hyzXwSJ1Fh+ooraUAJ+q7P2gg2kQF1nCFeGVjtV9m4ZrV5kZARcQMhp0Bp67tPo2TCtnthPYZS/YQG6u/6Aco1XZjPvuKujAQMGSgqNskhKBO9zfhhkAMIcKVryjKYHDfqbDUCCSNzlwFLts3nJ0Hfno6Hz+XxuBIfKOGjHfbzFyUQ7smYnzF23jFs4XhvnjmIGQJcZT4kQAsRwQubyuyDuqmQXqa+2SuQfkKTaPOlVqyuEWJdG2weIF8g3YP12czsBgNppz3jsnhEgstnQ==')


rsa = OpenSSL::PKey::RSA.new_from_parameters(n, e)
puts rsa

The goal is to have a clean Ruby implementation that does ssh-keygen -f <file> -e -m pem.

Now, comparing the results, they look very similar, but my code returns a few more bytes at the beginning of the key:

$ ssh-keygen -f ~/.ssh/id_rsa_perso.pub -e -m pem 
-----BEGIN RSA PUBLIC KEY-----
MIIBCAKCAQEA3RC8whKGFx+b7BMTFtnIWl6t/qyvOvnuqIrMNI9J8+1sEYv8Y/pJ
Rh0vAe2RaSKAgB2hyzXwSJ1Fh+ooraUAJ+q7P2gg2kQF1nCFeGVjtV9m4ZrV5kZA
RcQMhp0Bp67tPo2TCtnthPYZS/YQG6u/6Aco1XZjPvuKujAQMGSgqNskhKBO9zfh
hkAMIcKVryjKYHDfqbDUCCSNzlwFLts3nJ0Hfno6Hz+XxuBIfKOGjHfbzFyUQ7sm
YnzF23jFs4XhvnjmIGQJcZT4kQAsRwQubyuyDuqmQXqa+2SuQfkKTaPOlVqyuEWJ
dG2weIF8g3YP12czsBgNppz3jsnhEgstnQIBIw==
-----END RSA PUBLIC KEY-----
$ ruby ssh2x509.rb 
-----BEGIN PUBLIC KEY-----
MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA3RC8whKGFx+b7BMTFtnI
Wl6t/qyvOvnuqIrMNI9J8+1sEYv8Y/pJRh0vAe2RaSKAgB2hyzXwSJ1Fh+ooraUA
J+q7P2gg2kQF1nCFeGVjtV9m4ZrV5kZARcQMhp0Bp67tPo2TCtnthPYZS/YQG6u/
6Aco1XZjPvuKujAQMGSgqNskhKBO9zfhhkAMIcKVryjKYHDfqbDUCCSNzlwFLts3
nJ0Hfno6Hz+XxuBIfKOGjHfbzFyUQ7smYnzF23jFs4XhvnjmIGQJcZT4kQAsRwQu
byuyDuqmQXqa+2SuQfkKTaPOlVqyuEWJdG2weIF8g3YP12czsBgNppz3jsnhEgst
nQIBIw==
-----END PUBLIC KEY-----

Please note that my output has the contents of the output ssh-keygen, but with the addition MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0A.

What can cause these extra bytes and how can I get the correct result?

+1
source share
2 answers

It seems that the RSA key output format in Ruby OpenSSL was changed in 1.9.3 from PKCS # 1 (using OpenSSH) to X509 (using OpenSSL post 1.9.3):

https://redmine.ruby-lang.org/issues/4421

: PKCS # 1 :

ary = [OpenSSL::ASN1::Integer.new(n), OpenSSL::ASN1::Integer.new(e)]
pub_key = OpenSSL::ASN1::Sequence.new(ary)
base64 = Base64.encode64(pub_key.to_der)

#This is the equivalent to the PKCS#1 encoding used before 1.9.3
pem = "-----BEGIN RSA PUBLIC KEY-----\n#{base64}-----END RSA PUBLIC KEY-----"

, OpenSSL::PKey::RSA .

+2

, ASN1.

,

SEQUENCE(2 elem)
SEQUENCE(2 elem)
OBJECT IDENTIFIER1.2.840.113549.1.1.1
NULL
BIT STRING(1 elem)
SEQUENCE(2 elem)
INTEGER(2048 bit) 279069188856447290054297383130027286257044344789969750715307012565210…
INTEGER35

ssh

SEQUENCE(2 elem)
INTEGER(2048 bit) 279069188856447290054297383130027286257044344789969750715307012565210…
INTEGER35

? , RSA- -. SSH 2048 . , .

? , , ASN1.

hexdump, RSA.

RSA:

30 82 01 20 30 0D 06 09  2A 86 48 86 F7 0D 01 01
01 05 00 03 82 01 0D 00  **30 82 01 08 02 82 01 01
00 DD 10 BC C2** 12 86 17  1F 9B EC 13 13 16 D9 C8
5A 5E AD FE AC AF 3A F9  EE A8 8A CC 34 8F 49 F3
ED 6C 11 8B FC 63 FA 49  46 1D 2F 01 ED 91 69 22
80 80 1D A1 CB 35 F0 48  9D 45 87 EA 28 AD A5 00
27 EA BB 3F 68 20 DA 44  05 D6 70 85 78 65 63 B5
 skipping 160 bytes …
0F D7 67 33 B0 18 0D A6  9C F7 8E C9 E1 12 0B 2D
9D 02 01 23 

SSH RSA

**30 82 01 08 02 82 01 01  00 DD 10 BC C2** 12 86 17
1F 9B EC 13 13 16 D9 C8  5A 5E AD FE AC AF 3A F9
EE A8 8A CC 34 8F 49 F3  ED 6C 11 8B FC 63 FA 49
46 1D 2F 01 ED 91 69 22  80 80 1D A1 CB 35 F0 48
9D 45 87 EA 28 AD A5 00  27 EA BB 3F 68 20 DA 44
 skipping 160 bytes …
74 6D B0 78 81 7C 83 76  0F D7 67 33 B0 18 0D A6
9C F7 8E C9 E1 12 0B 2D  9D 02 01 23 

, , :

30 82 01 20 30 0D 06 09  2A 86 48 86 F7 0D 01 01
01 05 00 03 82 01 0D 00

24 . 24 .

ASN1 .

0

Source: https://habr.com/ru/post/1784298/


All Articles