来自模数和指数的SSH SubjectPublicKeyInfo [英] SSH SubjectPublicKeyInfo from modulus and exponent

查看:210
本文介绍了来自模数和指数的SSH SubjectPublicKeyInfo的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从公共SSH密钥中提取模数和指数,目的是生成PEM公共密钥.到目前为止,这是我的代码:

I'm extracting the modulus and exponent from a public SSH key with the goal of generating a PEM public key. Here is my code so far:

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

目标是实现ssh-keygen -f <file> -e -m pem的纯Ruby实现.

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

现在,比较结果,它们看起来非常相似,但是我的代码在键的开头又返回了几个字节:

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-----

请注意,我的输出包含ssh-keygen输出的内容,但前面带有MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0A.

Notice my output has the content of the ssh-keygen output, but with MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0A prepended.

什么可能导致这些额外的字节,如何获得正确的结果?

What could cause these extra bytes, and how could I get the proper result?

推荐答案

在Ruby OpenSSL中,RSA密钥的输出格式似乎在1.9.3中从PKCS#1(由OpenSSH使用)更改为X509(由OpenSSL发布使用) 1.9.3):

It seems the output format for RSA keys in Ruby OpenSSL was changed in 1.9.3 from PKCS#1 (used by OpenSSH) to X509 (used by OpenSSL post 1.9.3):

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

此错误报告中建议对用以下方法模拟PKCS#1 :

What is suggested in this bug report is to emulate the PKCS#1 with:

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的猴子补丁.

The monkey patching of OpenSSL::PKey::RSA is thus not necessary.

这篇关于来自模数和指数的SSH SubjectPublicKeyInfo的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆