Skip to content

Instantly share code, notes, and snippets.

@doolin
Forked from cky/csp2pem.rb
Last active December 30, 2022 00:34
Show Gist options
  • Save doolin/54bcd357f2ade3f6b5ba737abcef684a to your computer and use it in GitHub Desktop.
Save doolin/54bcd357f2ade3f6b5ba737abcef684a to your computer and use it in GitHub Desktop.
Quick script for converting PEM-format RSA keys to a format usable by .NET's RSA.FromXmlString
#!/usr/bin/ruby
require 'openssl'
TYPES = {
6 => {magic: 'RSA1', private_key: false},
7 => {magic: 'RSA2', private_key: true}
}
data = ARGV[0] ? File.binread(ARGV[0]) : $stdin.binmode.read
type, version, algo, magic, bits, rest = data.unpack('ccx2l<a4l<a*')
if match = TYPES[type]
raise 'Wrong magic' if magic != match[:magic]
private_key = match[:private_key]
else
raise 'Unsupported type'
end
raise 'Unsupported version' if version != 2
raise 'Unsupported algorithm' if ((algo >> 9) & 15) != 2
fields = [32, bits]
fields.push(*[bits / 2] * 5, bits) if private_key
key = OpenSSL::PKey::RSA.new
key.e, key.n, key.p, key.q, key.dmp1, key.dmq1, key.iqmp, key.d = fields.map do |bits|
size = (bits + 7) / 8
raise 'Unexpected end of data reached' if rest.size < size
OpenSSL::BN.new(rest.slice!(0, size).reverse!, 2)
end
raise 'Unexpected leftover data' unless rest.empty?
puts key.to_pem
#!/usr/bin/ruby
require 'nokogiri'
require 'openssl'
require 'byebug'
# https://ruby-doc.org/stdlib-3.1.0/libdoc/openssl/rdoc/OpenSSL/PKey/RSA.html
# https://ruby-doc.org/stdlib-3.1.0/libdoc/openssl/rdoc/OpenSSL/PKey.html
# Go the other way: https://groups.google.com/g/mailing.openssl.users/c/8hAgyv4SiFY
def base64(bn)
[bn.to_s(2)].pack('m0')
end
# key = OpenSSL::PKey::RSA.new(File.read($stdin))
# key = OpenSSL::PKey::RSA.new(File.read('../../.ssh/cqm.pem'))
key = OpenSSL::PKey::RSA.new(2048)
byebug
key = key.public_key
key = OpenSSL::PKey::RSA.new($stdin)
builder = Nokogiri::XML::Builder.new do |xml|
xml.RSAKeyValue do
xml.Modulus base64(key.n)
xml.Exponent base64(key.e)
if key.private?
xml.D base64(key.d)
xml.P base64(key.p)
xml.Q base64(key.q)
xml.DP base64(key.dmp1)
xml.DQ base64(key.dmq1)
xml.InverseQ base64(key.iqmp)
end
end
end
puts builder.to_xml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment