ruby - que - los certificados autofirmados causarán advertencias en el navegador
Ruby Generate Certificado autofirmado (3)
Intento generar un certificado autofirmado en ruby, pero estoy teniendo problemas. Esto es lo que tengo actualmente:
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 usar la clave privada y el certificado generados en apache, aparece 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 una CSR, que es lo que la mayoría de las cosas que he encontrado en línea dicen sobre ese error apache2 (que podría haber confundido el CSR y el CERT). 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 puedes hacer algo como esto:
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 larga pierda el enfoque en el camino.
EDITAR: Creo que la verdadera pregunta es cómo firmar un certificado con una clave
Desde entonces, he encontrado varias fuentes muy buenas para ejemplos que usan OpenSSL:
http://snippets.dzone.com/posts/show/6309
Todavía no he encontrado ninguna buena documentación para esto, aunque no creo que tarde demasiado en escribir lo que está en los ejemplos.
También descubrí 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.
Creé una clase de ayuda para esto a partir del código que saqué directamente de la esencia de nickyp que encontré en una búsqueda en Google. La única dependencia que necesitas es la gema 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-----
Hay un método create_self_signed_cert
en webrick/ssl
, que es fácil de entender y útil.