首页 文章

Ruby生成自签名证书

提问于
浏览
7

我正在尝试在ruby中生成自签名证书,但遇到了麻烦 . 这就是我现在所拥有的:

require 'openssl'

if ARGV.length != 3 then
    puts "USAGE: #{__FILE__} <type[der|pem]> <private-out> <public-out>"
    exit
end

type = ARGV[0].downcase
privateKeyFile = ARGV[1]
publicKeyFile = ARGV[2]

values = [{ 'C' => 'US'},
          {'ST' => 'SomeState'},
          { 'L' => 'SomeCity'},
          { 'O' => 'Organization'},
          {'OU' => 'Organizational Unit'},
          {'CN' => "somesite.com"}]

name = values.collect{ |l| l.collect { |k, v| "/#{k}=#{v}" }.join }.join

key = OpenSSL::PKey::RSA.generate(1024)
pub = key.public_key
ca = OpenSSL::X509::Name.parse(name)
cert = OpenSSL::X509::Certificate.new
cert.version = 2 
cert.serial = 1 
cert.subject = ca
cert.issuer = ca
cert.public_key = pub 
cert.not_before = Time.now
cert.not_before = Time.now + (360 * 24 * 3600)

File.open(privateKeyFile + "." + type, "w") {|f| f.write key.send("to_#{type}") }
File.open(publicKeyFile + "." + type, "w") {|f| f.write cert.send("to_#{type}") }

当我尝试在apache中使用生成的私钥和证书时,我收到此错误:

[Thu Mar 04 10:58:44 2010] [error] Init: Unable to read server certificate from file /etc/ssl/certs/gnarly.pem
[Thu Mar 04 10:58:44 2010] [error] SSL Library Error: 218529960 error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
[Thu Mar 04 10:58:44 2010] [error] SSL Library Error: 218595386 error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error

这是我的证书所说的:

-----BEGIN CERTIFICATE-----
<lots of stuff>
-----END CERTIFICATE-----

它自称为证书而不是CSR,这就是我在网上找到的大部分内容都说明了apache2错误(我可能已经将CSR和CERT混淆了) . 我的猜测是我没有生成正确类型的证书 . 也许我必须更改序列或版本属性 . 另外,我不会在任何地方进行任何自我签名,而不是我所知道的 . 我知道你可以这样做:

require "openssl"
key = OpenSSL::PKey::RSA.generate(1024)
signature = key.sign(OpenSSL::Digest::SHA1.new, "data to sign")

提醒:我的目标是生成一个自签名证书,以防我的长期问题失去焦点 .

编辑:我想真正的问题是如何用密钥签署证书

3 回答

  • 1

    我从我在Google搜索中找到的直接从nickyp's gist提取的代码创建了一个帮助类 . 你需要的唯一依赖是openssl gem( gem install openssl

    require 'openssl'
    
    class SelfSignedCertificate
      def initialize
        @key = OpenSSL::PKey::RSA.new(1024)
        public_key = @key.public_key
    
        subject = "/C=BE/O=Test/OU=Test/CN=Test"
    
        @cert = OpenSSL::X509::Certificate.new
        @cert.subject = @cert.issuer = OpenSSL::X509::Name.parse(subject)
        @cert.not_before = Time.now
        @cert.not_after = Time.now + 365 * 24 * 60 * 60
        @cert.public_key = public_key
        @cert.serial = 0x0
        @cert.version = 2
    
        ef = OpenSSL::X509::ExtensionFactory.new
        ef.subject_certificate = @cert
        ef.issuer_certificate = @cert
        @cert.extensions = [
            ef.create_extension("basicConstraints","CA:TRUE", true),
            ef.create_extension("subjectKeyIdentifier", "hash"),
        # ef.create_extension("keyUsage", "cRLSign,keyCertSign", true),
        ]
        @cert.add_extension ef.create_extension("authorityKeyIdentifier",
                                               "keyid:always,issuer:always")
    
        @cert.sign @key, OpenSSL::Digest::SHA1.new
      end
    
      def self_signed_pem
        @cert.to_pem
      end
    
      def private_key
        @key
      end
    end
    

    Usage:

    my_cert = SelfSignedCertificate.new
    puts "Private Key:\n#{my_cert.private_key}"
    puts "Self-signed PEM:\n#{my_cert.self_signed_pem}"
    

    Output:

    Private Key:
    -----BEGIN RSA PRIVATE KEY-----
    MIICXQIBAAKBgQDTtjPd3X9KX9BZpXKS82tM74Bs/hXsSLgnkitrc+oR4oF5PVko
    NZL3j51gkX3jJRSG9tNPQC5NVR+5h7tXPxU5TAQZl6MUiV+YWuRng98GeCjP3ePp
    meSStsKEMUiZI8YLVWrdbIjS+Q+lZnYMffeEOAoMSaei9hR4rOX0i+9hdwIDAQAB
    AoGBALdAc/6sFd0zuC2Qhu7p4kvS11AAUsuWWkhuPkUhLU9TxwxBbOXgEZlVZzzK
    UrQFSZJVHazweeOYNgCqmx82zE+cB4YzRLqkCPUD9t1bZcgk31tV39MSrC9CDKCB
    inUTMKflPbHL0B+Lq24S8KfuW9bOPofhspjlV7cZCX5adFiBAkEA7KOMkiQMyq9X
    ZVeRzJU0LmVdjrb7UBD5NebV+KaN8O7q+W4FG0nihcNj7xt2fZnvKM4FMfRwDP3G
    HRUfR0alQQJBAOUIjKXYyoUsk+tLASoYLX+uPocjd7YSB9UPK2lFxqHOzekAlynF
    u1JWEDPOjZNtNHmsQKOp5AWTUnm33JxfQLcCQByY5zQCB0m3RuiIXKZMobG5rkTA
    +D4EzxkkfFdASYcEWIEsOpHBrA5ePoV23Crxn2VfAGG5GJF5WafKFa2XbAECQFL/
    5Ch+BfZ5DynnxoZAuMxakuJaYhmjMx9tHehKlw8waMKVqjJDK/1MnxaHNhtFKg0l
    9U7aVH4Iw4zEqrgodMUCQQCWZEUepSGoRVs1YDtag4FKSTMGXcnI/jllJmxHQhf4
    uiy/8Hb+FW49w3KO1zeq7WdXw7W7Q1uO94npYX5p535d
    -----END RSA PRIVATE KEY-----
    Signed PEM:
    -----BEGIN CERTIFICATE-----
    MIICgjCCAeugAwIBAgIBADANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJCRTEN
    MAsGA1UECgwEVGVzdDENMAsGA1UECwwEVGVzdDENMAsGA1UEAwwEVGVzdDAeFw0x
    NDA4MjEwMTI1MTZaFw0xNTA4MjEwMTI1MTZaMDoxCzAJBgNVBAYTAkJFMQ0wCwYD
    VQQKDARUZXN0MQ0wCwYDVQQLDARUZXN0MQ0wCwYDVQQDDARUZXN0MIGfMA0GCSqG
    SIb3DQEBAQUAA4GNADCBiQKBgQDTtjPd3X9KX9BZpXKS82tM74Bs/hXsSLgnkitr
    c+oR4oF5PVkoNZL3j51gkX3jJRSG9tNPQC5NVR+5h7tXPxU5TAQZl6MUiV+YWuRn
    g98GeCjP3ePpmeSStsKEMUiZI8YLVWrdbIjS+Q+lZnYMffeEOAoMSaei9hR4rOX0
    i+9hdwIDAQABo4GXMIGUMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNNbdqck
    QT/B5hdQqimtW1Wnf+fmMGIGA1UdIwRbMFmAFNNbdqckQT/B5hdQqimtW1Wnf+fm
    oT6kPDA6MQswCQYDVQQGEwJCRTENMAsGA1UECgwEVGVzdDENMAsGA1UECwwEVGVz
    dDENMAsGA1UEAwwEVGVzdIIBADANBgkqhkiG9w0BAQUFAAOBgQB80KzzhkXCgJ0s
    1zXJXuocNDU5v0Z42ditNX9jS8pXuhHwcQbx7PVfOieO3GHC5YzzgMHGR3i2U2CQ
    rz9hP937ERxCfqpxhfMAD3Q+3rHsdGdNIauzzFb6XoXsM7koRnM27I6qvO3bamcz
    AVGH5eLic9IjZTQbZizFzNoR+H2N/g==
    -----END CERTIFICATE-----
    
  • 6

    webrick/ssl 中有一个 create_self_signed_cert 方法,它易于理解和有用 .

  • 2

    我已经使用OpenSSL找到了几个非常好的示例来源:

    http://snippets.dzone.com/posts/show/6309

    http://projects.reductivelabs.com/projects/puppet/repository/revisions/master/entry/lib/puppet/sslcertificates.rb

    http://projects.reductivelabs.com/projects/puppet/repository/revisions/master/entry/lib/puppet/sslcertificates/ca.rb

    http://projects.reductivelabs.com/projects/puppet/repository/revisions/master/entry/lib/puppet/sslcertificates/certificate.rb

    我还没有找到任何好的文档,尽管我认为写下示例中的内容并不需要太长时间 .

    我也想出了如何从puppet源代码中做我想做的事情 . 希望这可以帮助那些对ruby中缺少OpenSSL文档感到沮丧的人 .

相关问题