2010-03-04 25 views
7

Estoy tratando de generar un certificado autofirmado en ruby, pero estoy teniendo problemas. Esto es lo que actualmente tengo en este momento:Ruby Generar certificado autofirmado

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}") } 

Cuando trato de utilizar la clave privada y un certificado generados en Apache, me sale este error:

[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 

Esto es lo que dice mi certificado:

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

Se llama a sí mismo un certificado en lugar de un CSR, que es lo que la mayoría de las cosas que he encontrado en línea dicen que el error sobre apache2 (que podría haber conseguido la RSE y el CERT mezclado). Supongo que no estoy generando el tipo correcto de certificado. Tal vez tengo que cambiar los atributos de serie o versión. Además, no estoy haciendo autofirma en ninguna parte, no es que yo sepa de todos modos. Sé que usted puede hacer algo como esto, sin embargo:

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

Recordatorio: Mi objetivo es generar un certificado autofirmado, en caso de que mi pregunta largo ish perdido el foco en el camino.

EDIT: supongo que la pregunta real es cómo firmar un certificado con una clave

+0

Cualquiera que estará interesado preparé exammple RSE en ruby, puedes encontrarlo aquí: https://gist.github.com/1922961 – mtfk

Respuesta

2

ya que he encontrado varias fuentes muy buenas para los ejemplos usando 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

Todavía no he encontrado ninguna buena documentación para esto, aunque no creo que tarde demasiado en escribir lo que hay en los ejemplos.

También he descubierto cómo hacer lo que quería del código fuente de la marioneta. Espero que esto ayude a alguien más que está frustrado por la falta de documentación de OpenSSL en ruby.

+9

Ah ... la transitoria na tura de la web. Menos de 2 años después, todos los enlaces anteriores están rotos. –

+0

La estructura de la fuente de Puppet también ha cambiado, pero la misma información general se puede obtener de su repositorio de GitHub: https://github.com/puppetlabs/puppet/tree/master/lib/puppet/ssl –

1

Hay un método create_self_signed_cert en webrick/ssl, que es fácil de entender y útil.

+0

puede proporcionar un ejemplo de uso? – Nabheet

+0

'cert, rsa = WEBrick :: Utils.create_self_signed_cert 1024, [[" CN "," localhost "]]," '' – puchu

4

Creé una clase de ayuda para esto desde el código que levanté directamente desde nickyp's gist que encontré en una búsqueda en Google. La única dependencia que necesita es la joya openssl (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 

Uso:

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

Salida:

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