来自模数和指数的SSH SubjectPublicKeyInfo [英] SSH SubjectPublicKeyInfo from modulus and exponent
问题描述
我正在从公共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屋!