¿Cómo se firma una solicitud de firma de certificado con su autoridad de certificación?

Durante mi búsqueda, encontré varias formas de firmar una Solicitud de firma de certificado SSL:

  1. Usando el módulo x509 :

     openssl x509 -req -days 360 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt 
  2. Usando el módulo ca :

     openssl ca -cert ca.crt -keyfile ca.key -in server.csr -out server.crt 

Nota: No estoy seguro del uso de los parámetros correctos para este. Aconseja el uso correcto si debo usarlo.

¿De qué manera debe uno usar para firmar solicitudes de certificados con su Autoridad de Certificación? ¿Un método es mejor que el otro (por ejemplo, uno está en desuso)?

 1. Using the x509 module openssl x509 ... ... 2 Using the ca module openssl ca ... ... 

Lo que te estás perdiendo es el preludio de esos comandos.

Este es un proceso de dos pasos. Primero configura su CA y luego firma un certificado de entidad final (también conocido como servidor o usuario). Los dos comandos elide los dos pasos en uno. Y ambos asumen que tiene un archivo de configuración de OpenSSL ya configurado para las CA y los certificados del servidor (entidad final).


Primero, crea un archivo de configuración básico:

 $ touch openssl-ca.cnf 

Luego, agregue lo siguiente a esto:

 HOME = . RANDFILE = $ENV::HOME/.rnd #################################################################### [ ca ] default_ca = CA_default # The default ca section [ CA_default ] default_days = 1000 # how long to certify for default_crl_days = 30 # how long before next CRL default_md = sha256 # use public key default MD preserve = no # keep passed DN ordering x509_extensions = ca_extensions # The extensions to add to the cert email_in_dn = no # Don't concat the email in the DN copy_extensions = copy # Required to copy SANs from CSR to cert #################################################################### [ req ] default_bits = 4096 default_keyfile = cakey.pem distinguished_name = ca_distinguished_name x509_extensions = ca_extensions string_mask = utf8only #################################################################### [ ca_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = US stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Maryland localityName = Locality Name (eg, city) localityName_default = Baltimore organizationName = Organization Name (eg, company) organizationName_default = Test CA, Limited organizationalUnitName = Organizational Unit (eg, division) organizationalUnitName_default = Server Research Department commonName = Common Name (eg server FQDN or YOUR name) commonName_default = Test CA emailAddress = Email Address emailAddress_default = test@example.com #################################################################### [ ca_extensions ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always, issuer basicConstraints = critical, CA:true keyUsage = keyCertSign, cRLSign 

Los campos de arriba se tomaron de un openssl.cnf más complejo (puede encontrarlo en /usr/lib/openssl.cnf ), pero creo que son los elementos esenciales para crear el certificado de CA y la clave privada.

Ajusta los campos de arriba para que se adapten a tu gusto. Los valores predeterminados le ahorran tiempo al ingresar la misma información mientras experimenta con el archivo de configuración y las opciones de comando.

Omití el material relevante de CRL, pero sus operaciones de CA deben tenerlos. Ver openssl.cnf y la sección relacionada crl_ext .

Luego, ejecuta lo siguiente. Los -nodes omiten la contraseña o frase de contraseña para que pueda examinar el certificado. Es una mala idea omitir la contraseña o frase de contraseña.

 $ openssl req -x509 -config openssl-ca.cnf -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM 

Después de que se ejecuta el comando, cacert.pem será su certificado para las operaciones de CA, y cakey.pem será la clave privada. Recuerde que la clave privada no tiene una contraseña o frase de contraseña.

Puede volcar el certificado con lo siguiente.

 $ openssl x509 -in cacert.pem -text -noout Certificate: Data: Version: 3 (0x2) Serial Number: 11485830970703032316 (0x9f65de69ceef2ffc) Signature Algorithm: sha256WithRSAEncryption Issuer: C=US, ST=MD, L=Baltimore, CN=Test CA/emailAddress=test@example.com Validity Not Before: Jan 24 14:24:11 2014 GMT Not After : Feb 23 14:24:11 2014 GMT Subject: C=US, ST=MD, L=Baltimore, CN=Test CA/emailAddress=test@example.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (4096 bit) Modulus: 00:b1:7f:29:be:78:02:b8:56:54:2d:2c:ec:ff:6d: ... 39:f9:1e:52:cb:8e:bf:8b:9e:a6:93:e1:22:09:8b: 59:05:9f Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 4A:9A:F3:10:9E:D7:CF:54:79:DE:46:75:7A:B0:D0:C1:0F:CF:C1:8A X509v3 Authority Key Identifier: keyid:4A:9A:F3:10:9E:D7:CF:54:79:DE:46:75:7A:B0:D0:C1:0F:CF:C1:8A X509v3 Basic Constraints: critical CA:TRUE X509v3 Key Usage: Certificate Sign, CRL Sign Signature Algorithm: sha256WithRSAEncryption 4a:6f:1f:ac:fd:fb:1e:a4:6d:08:eb:f5:af:f6:1e:48:a5:c7: ... cd:c6:ac:30:f9:15:83:41:c1:d1:20:fa:85:e7:4f:35:8f:b5: 38:ff:fd:55:68:2c:3e:37 

Y pruebe su propósito con lo siguiente (no se preocupe por ningún Any Purpose: Yes , vea “crítico, CA: FALSO” pero “CA de cualquier propósito: sí” ).

 $ openssl x509 -purpose -in cacert.pem -inform PEM Certificate purposes: SSL client : No SSL client CA : Yes SSL server : No SSL server CA : Yes Netscape SSL server : No Netscape SSL server CA : Yes S/MIME signing : No S/MIME signing CA : Yes S/MIME encryption : No S/MIME encryption CA : Yes CRL signing : Yes CRL signing CA : Yes Any Purpose : Yes Any Purpose CA : Yes OCSP helper : Yes OCSP helper CA : Yes Time Stamp signing : No Time Stamp signing CA : Yes -----BEGIN CERTIFICATE----- MIIFpTCCA42gAwIBAgIJAJ9l3mnO7y/8MA0GCSqGSIb3DQEBCwUAMGExCzAJBgNV ... aQUtFrV4hpmJUaQZ7ySr/RjCb4KYkQpTkOtKJOU1Ic3GrDD5FYNBwdEg+oXnTzWP tTj//VVoLD43 -----END CERTIFICATE----- 

Para la segunda parte, voy a crear otro archivo conf que sea fácilmente digerible. Primero, touch el openssl-server.cnf (también puede hacer uno de estos para los certificados del usuario).

 $ touch openssl-server.cnf 

Luego ábralo y agregue lo siguiente.

 HOME = . RANDFILE = $ENV::HOME/.rnd #################################################################### [ req ] default_bits = 2048 default_keyfile = serverkey.pem distinguished_name = server_distinguished_name req_extensions = server_req_extensions string_mask = utf8only #################################################################### [ server_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = US stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = MD localityName = Locality Name (eg, city) localityName_default = Baltimore organizationName = Organization Name (eg, company) organizationName_default = Test Server, Limited commonName = Common Name (eg server FQDN or YOUR name) commonName_default = Test Server emailAddress = Email Address emailAddress_default = test@example.com #################################################################### [ server_req_extensions ] subjectKeyIdentifier = hash basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment subjectAltName = @alternate_names nsComment = "OpenSSL Generated Certificate" #################################################################### [ alternate_names ] DNS.1 = example.com DNS.2 = www.example.com DNS.3 = mail.example.com DNS.4 = ftp.example.com 

Si está desarrollando y necesita usar su estación de trabajo como servidor, entonces puede necesitar hacer lo siguiente para Chrome. De lo contrario, Chrome puede quejarse de que un Nombre común no es válido ( ERR_CERT_COMMON_NAME_INVALID ) . No estoy seguro de cuál es la relación entre una dirección IP en la SAN y una CN en esta instancia.

 # IPv4 localhost IP.1 = 127.0.0.1 # IPv6 localhost IP.2 = ::1 

Luego, crea la solicitud de certificado del servidor. Asegúrese de omitir -x509 *. Agregar -x509 creará un certifcado y no una solicitud.

 $ openssl req -config openssl-server.cnf -newkey rsa:2048 -sha256 -nodes -out servercert.csr -outform PEM 

Después de que se ejecute este comando, tendrá una solicitud en servercert.csr y una clave privada en serverkey.pem .

Y puedes inspeccionarlo de nuevo.

 $ openssl req -text -noout -verify -in servercert.csr Certificate: verify OK Certificate Request: Version: 0 (0x0) Subject: C=US, ST=MD, L=Baltimore, CN=Test Server/emailAddress=test@example.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:ce:3d:58:7f:a0:59:92:aa:7c:a0:82:dc:c9:6d: ... f9:5e:0c:ba:84:eb:27:0d:d9:e7:22:5d:fe:e5:51: 86:e1 Exponent: 65537 (0x10001) Attributes: Requested Extensions: X509v3 Subject Key Identifier: 1F:09:EF:79:9A:73:36:C1:80:52:60:2D:03:53:C7:B6:BD:63:3B:61 X509v3 Basic Constraints: CA:FALSE X509v3 Key Usage: Digital Signature, Key Encipherment X509v3 Subject Alternative Name: DNS:example.com, DNS:www.example.com, DNS:mail.example.com, DNS:ftp.example.com Netscape Comment: OpenSSL Generated Certificate Signature Algorithm: sha256WithRSAEncryption 6d:e8:d3:85:b3:88:d4:1a:80:9e:67:0d:37:46:db:4d:9a:81: ... 76:6a:22:0a:41:45:1f:e2:d6:e4:8f:a1:ca:de:e5:69:98:88: a9:63:d0:a7 

Luego, debe firmarlo con su CA.


Ya está casi listo para firmar el certificado del servidor por parte de su CA. El openssl-ca.cnf necesita dos secciones más antes de emitir el comando.

Primero, abra openssl-ca.cnf y agregue las dos secciones siguientes.

 #################################################################### [ signing_policy ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional #################################################################### [ signing_req ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment 

En segundo lugar, agregue lo siguiente a la sección [ CA_default ] de openssl-ca.cnf . Los dejé antes porque pueden complicar las cosas (no se usaron en ese momento). Ahora verás cómo se usan, así que con suerte tendrán sentido.

 base_dir = . certificate = $base_dir/cacert.pem # The CA certifcate private_key = $base_dir/cakey.pem # The CA private key new_certs_dir = $base_dir # Location for new certs after signing database = $base_dir/index.txt # Database index file serial = $base_dir/serial.txt # The current serial number unique_subject = no # Set to 'no' to allow creation of # several certificates with same subject. 

En tercer lugar, toque index.txt y serial.txt :

 $ touch index.txt $ echo '01' > serial.txt 

Luego, realice lo siguiente:

 $ openssl ca -config openssl-ca.cnf -policy signing_policy -extensions signing_req -out servercert.pem -infiles servercert.csr 

Debería ver algo similar a lo siguiente:

 Using configuration from openssl-ca.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'US' stateOrProvinceName :ASN.1 12:'MD' localityName :ASN.1 12:'Baltimore' commonName :ASN.1 12:'Test CA' emailAddress :IA5STRING:'test@example.com' Certificate is to be certified until Oct 20 16:12:39 2016 GMT (1000 days) Sign the certificate? [y/n]:Y 1 out of 1 certificate requests certified, commit? [y/n]Y Write out database with 1 new entries Data Base Updated 

Después de que se ejecute el comando, tendrá un certificado de servidor recién acuñado en servercert.pem . La clave privada se creó anteriormente y está disponible en serverkey.pem .

Finalmente, puede inspeccionar su certificado recién acuñado con lo siguiente.

 $ openssl x509 -in servercert.pem -text -noout Certificate: Data: Version: 3 (0x2) Serial Number: 9 (0x9) Signature Algorithm: sha256WithRSAEncryption Issuer: C=US, ST=MD, L=Baltimore, CN=Test CA/emailAddress=test@example.com Validity Not Before: Jan 24 19:07:36 2014 GMT Not After : Oct 20 19:07:36 2016 GMT Subject: C=US, ST=MD, L=Baltimore, CN=Test Server Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:ce:3d:58:7f:a0:59:92:aa:7c:a0:82:dc:c9:6d: ... f9:5e:0c:ba:84:eb:27:0d:d9:e7:22:5d:fe:e5:51: 86:e1 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 1F:09:EF:79:9A:73:36:C1:80:52:60:2D:03:53:C7:B6:BD:63:3B:61 X509v3 Authority Key Identifier: keyid:42:15:F2:CA:9C:B1:BB:F5:4C:2C:66:27:DA:6D:2E:5F:BA:0F:C5:9E X509v3 Basic Constraints: CA:FALSE X509v3 Key Usage: Digital Signature, Key Encipherment X509v3 Subject Alternative Name: DNS:example.com, DNS:www.example.com, DNS:mail.example.com, DNS:ftp.example.com Netscape Comment: OpenSSL Generated Certificate Signature Algorithm: sha256WithRSAEncryption b1:40:f6:34:f4:38:c8:57:d4:b6:08:f7:e2:71:12:6b:0e:4a: ... 45:71:06:a9:86:b6:0f:6d:8d:e1:c5:97:8d:fd:59:43:e9:3c: 56:a5:eb:c8:7e:9f:6b:7a 

Anteriormente, agregó lo siguiente a CA_default : copy_extensions = copy . Esto copia la extensión provista por la persona que realiza la solicitud.

Si omite copy_extensions = copy , su certificado de servidor carecerá de los nombres alternativos del sujeto (SAN) como www.example.com y mail.example.com .

Si usa copy_extensions = copy pero no copy_extensions = copy la solicitud, entonces el solicitante podría engañarlo para que firme algo así como una raíz subordinada (en lugar de un servidor o certificado de usuario). Lo que significa que será capaz de acuñar certificados que encadenan a su raíz de confianza. Asegúrese de verificar la solicitud con openssl req -verify antes de firmar.


Si omite unique_subject o lo establece en yes , solo se le permitirá crear un certificado con el nombre unique_subject del sujeto.

 unique_subject = yes # Set to 'no' to allow creation of # several ctificates with same subject. 

Intentar crear un segundo certificado mientras se experimenta generará lo siguiente al firmar el certificado de su servidor con la clave privada de la CA:

 Sign the certificate? [y/n]:Y failed to update database TXT_DB error number 2 

Entonces unique_subject = no es perfecto para probar.


Si desea asegurarse de que el Nombre de la organización sea coherente entre las CA con firma propia, la CA subordinada y los certificados de Entidad final, agregue lo siguiente a sus archivos de configuración de CA:

 [ policy_match ] organizationName = match 

Si desea permitir que el nombre de la organización cambie, entonces use:

 [ policy_match ] organizationName = supplied 

Existen otras reglas sobre el manejo de nombres DNS en certificados X.509 / PKIX. Consulte estos documentos para conocer las reglas:

  • RFC 5280, Internet X.509 Certificado de infraestructura de claves públicas y lista de revocación de certificados (CRL)
  • RFC 6125, Representación y verificación de la identidad del servicio de aplicación basada en dominio dentro de la infraestructura de clave pública de Internet utilizando los certificados X.509 (PKIX) en el contexto de la seguridad de la capa de transporte (TLS)
  • RFC 6797, Apéndice A, HTTP Strict Transport Security (HSTS)
  • RFC 7469, extensión de vinculación de clave pública para HTTP
  • Requisitos de Baseline del CA / Browser Forum
  • Directrices de validación ampliada de CA / Browser Forum

RFC 6797 y RFC 7469 se enumeran porque son más restrictivos que los otros documentos RFC y CA / B. RFC’s 6797 y 7469 tampoco permiten una dirección IP.

Además de la respuesta de @jww, me gustaría decir que la configuración en openssl-ca.cnf

 default_days = 1000 # how long to certify for 

define el número predeterminado de días en que el certificado firmado por este root-ca será válido; para establecer la validez de root-ca, debe usar la opción ‘-days n’ en

 openssl req -x509 -days 3000 -config openssl-ca.cnf -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM 

Si no lo hace, su root-ca será válido solo por defecto 1 mes y cualquier certificado firmado por este rot-ca también tendrá validez de 1 mes.

    Intereting Posts