¿Cómo generar un certificado SSL autofirmado usando OpenSSL?

1598

Estoy agregando compatibilidad con HTTPS a un dispositivo Linux integrado. Intenté generar un certificado autofirmado con estos pasos:

openssl req -new > cert.csr
openssl rsa -in privkey.pem -out key.pem
openssl x509 -in cert.csr -out cert.pem -req -signkey key.pem -days 1001
cat key.pem>>cert.pem

Esto funciona, pero obtengo algunos errores con, por ejemplo, Google Chrome:

This is probably not the site you are looking for!
The site's security certificate is not trusted!

¿Me estoy perdiendo de algo? ¿Es esta la forma correcta de crear un certificado autofirmado?

6
  • 53
    Los certificados autofirmados se consideran inseguros para Internet. Firefox tratará el sitio como si tuviera un certificado no válido, mientras que Chrome actuará como si la conexión fuera HTTP simple. Más detalles: gerv.net/security/self-signed-certs 16/04/12 a las 14:17
  • 47
    Debe importar su certificado de CA a sus navegadores y decirles a los navegadores que confía en el certificado, o bien, que lo firme una de las organizaciones de gran dinero por nada en las que ya confían los navegadores, o bien, ignore la advertencia y haga clic en más allá de él. Yo mismo me gusta la última opción. 16/04/12 a las 14:20
  • dieciséis
    No debe utilizar la configuración "estándar" de OpenSSL de esa manera. Esto se debe a que no puede colocar nombres DNS en el nombre alternativo del sujeto (SAN). Debe proporcionar un archivo de configuración con una alternate_namessección y pasarlo con la -configopción. Además, la colocación de un nombre DNS en el nombre común (CN) está en desuso (pero no está prohibido) tanto por el IETF como por los foros de CA / navegador. Cualquier nombre DNS en el CN ​​también debe estar presente en el SAN. No hay forma de evitar el uso de SAN. Vea la respuesta a continuación.
    jww
    13/01/15 a las 22:01
  • 6
    Además del comentario de @jww. Para mayo de 2017, Chrome ya no acepta certificados sin SAN (emtpy): "El certificado para este sitio no contiene una extensión de nombre alternativo del sujeto que contenga un nombre de dominio o una dirección IP". 25 de mayo de 2017 a las 7:35
  • 8
    En estos días, siempre que se pueda acceder a su servidor web mediante su FQDN en el puerto 80 a través de Internet, puede usar LetsEncrypt y obtener certificados de CA completos gratuitos (válidos por 90 días, la renovación se puede automatizar) que no darán ninguna advertencia al navegador / mensajes. www.letsencrypt.com
    balmy
    27/03/18 a las 12:13
2581

Puedes hacerlo con un comando:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

También puede agregar -nodes(abreviatura de no DES) si no desea proteger su clave privada con una frase de contraseña. De lo contrario, le pedirá una contraseña de "al menos 4 caracteres".

El daysparámetro (365) se puede reemplazar con cualquier número para afectar la fecha de vencimiento. Luego le pedirá cosas como "Nombre de país", pero puede presionar Entery aceptar los valores predeterminados.

Agregue -subj '/CN=localhost'para suprimir preguntas sobre el contenido del certificado (reemplácelo localhostcon el dominio que desee).

Los certificados autofirmados no se validan con ningún tercero a menos que los importe a los navegadores previamente. Si necesita más seguridad, debe utilizar un certificado firmado por una autoridad de certificación (CA).

31
  • 14
    Para cualquiera que esté interesado, aquí está la documentación , si desea verificar algo usted mismo.
    user456814
    15/04/2014 a las 17:34
  • 21
    ¿De qué manera la firma con un tercero proporciona más seguridad? 11/07/2014 a las 3:14
  • 264
    Para cualquier otra persona que use esto en la automatización, aquí están todos los parámetros comunes para el tema: -subj "/C=US/ST=Oregon/L=Portland/O=Company Name/OU=Org/CN=www.example.com"
    Alex S
    5/06/2015 a las 18:13
  • 42
    @JamesMills Quiero decir, piénsalo: si un tipo de aspecto sombrío con "dulces gratis" escrito en el costado de su camioneta te invita a entrar, lo pensarás dos veces y estarás en guardia, pero Si alguien en quien confías, como en quien realmente confías, es como, "no, hombre, es legítimo", vas a tener que ver con los dulces gratis. 18 dic 2015 a las 23:39
  • 85
    Recuerde utilizar -sha256para generar un certificado basado en SHA-256. 25 de enero de 2016 a las 6:13
607

Am I missing something? Is this the correct way to build a self-signed certificate?

Es fácil crear un certificado autofirmado. Solo usa el openssl reqcomando. Puede resultar complicado crear uno que pueda ser consumido por la mayor selección de clientes, como navegadores y herramientas de línea de comandos.

Es difícil porque los navegadores tienen su propio conjunto de requisitos y son más restrictivos que el IETF . Los requisitos utilizados por los navegadores están documentados en CA / Browser Forums (consulte las referencias a continuación). Las restricciones surgen en dos áreas clave: (1) anclajes de confianza y (2) nombres DNS.

Los navegadores modernos (como el warez que estamos usando en 2014/2015) quieren un certificado que vuelva a encadenar a un ancla de confianza, y quieren que los nombres DNS se presenten de formas particulares en el certificado. Y los navegadores se están moviendo activamente contra los certificados de servidor autofirmados.

Algunos navegadores no facilitan exactamente la importación de un certificado de servidor autofirmado. De hecho, no puede hacerlo con algunos navegadores, como el navegador de Android. Entonces, la solución completa es convertirse en su propia autoridad.

En ausencia de convertirse en su propia autoridad, debe obtener los nombres DNS correctos para darle al certificado la mayor probabilidad de éxito. Pero le animo a que se convierta en su propia autoridad. Es fácil convertirse en su propia autoridad y evitará todos los problemas de confianza (¿en quién mejor para confiar que en usted mismo?).


This is probably not the site you are looking for!
The site's security certificate is not trusted!

Esto se debe a que los navegadores utilizan una lista predefinida de anclajes de confianza para validar los certificados del servidor. Un certificado autofirmado no se vuelve a encadenar a un ancla de confianza.

La mejor forma de evitarlo es:

  1. Cree su propia autoridad (es decir, conviértase en CA )
  2. Cree una solicitud de firma de certificado (CSR) para el servidor
  3. Firme la CSR del servidor con su clave CA
  4. Instale el certificado del servidor en el servidor
  5. Instale el certificado CA en el cliente

Paso 1: crear su propia autoridad solo significa crear un certificado autofirmado con CA: trueel uso adecuado de la clave. Eso significa que el sujeto y el emisor son la misma entidad, CA se establece en verdadero en Restricciones básicas (también debe marcarse como crítico), el uso de la clave es keyCertSigny crlSign(si está utilizando CRL) y el Identificador de clave del sujeto (SKI) es lo mismo que el Identificador de clave de autoridad (AKI).

Para convertirse en su propia autoridad de certificación, consulte * ¿Cómo se firma una solicitud de firma de certificado con su autoridad de certificación? en Stack Overflow. Luego, importe su CA a Trust Store que utiliza el navegador.

Los pasos 2 a 4 son aproximadamente lo que hace ahora para un servidor público cuando contrata los servicios de una CA como Startcom o CAcert . Los pasos 1 y 5 le permiten evitar la autoridad de terceros y actuar como su propia autoridad (¿en quién mejor para confiar que en usted mismo?).

La siguiente mejor forma de evitar la advertencia del navegador es confiar en el certificado del servidor. Pero algunos navegadores, como el navegador predeterminado de Android, no te permiten hacerlo. Por lo tanto, nunca funcionará en la plataforma.

El problema de los navegadores (y otros agentes de usuario similares) que no confían en los certificados autofirmados será un gran problema en la Internet de las cosas (IoT). Por ejemplo, ¿qué va a pasar cuando te conectes a tu termostato o frigorífico para programarlo? La respuesta es, nada bueno en lo que respecta a la experiencia del usuario.

El grupo de trabajo WebAppSec del W3C está empezando a analizar el problema. Consulte, por ejemplo, Propuesta: Marcar HTTP como no seguro .


How to create a self-signed certificate with OpenSSL

Los siguientes comandos y el archivo de configuración crean un certificado autofirmado (también muestra cómo crear una solicitud de firma). Se diferencian de otras respuestas en un aspecto: los nombres DNS utilizados para el certificado autofirmado están en el nombre alternativo del sujeto (SAN) y no en el nombre común (CN) .

Los nombres DNS se colocan en la SAN a través del archivo de configuración con la línea subjectAltName = @alternate_names(no hay forma de hacerlo a través de la línea de comandos). Luego hay una alternate_namessección en el archivo de configuración (debe ajustar esto a su gusto):

[ alternate_names ]

DNS.1       = example.com
DNS.2       = www.example.com
DNS.3       = mail.example.com
DNS.4       = ftp.example.com

# Add these if you need them. But usually you don't want them or
#   need them in production. You may need them for development.
# DNS.5       = localhost
# DNS.6       = localhost.localdomain
# IP.1        = 127.0.0.1
# IP.2        = ::1

Es importante poner el nombre DNS en la SAN y no en el CN, porque tanto el IETF como los foros de CA / navegador especifican la práctica. También especifican que los nombres DNS en el CN ​​están obsoletos (pero no prohibidos). Si coloca un nombre DNS en el CN, debe incluirse en el SAN según las políticas de CA / B. Por lo tanto, no puede evitar usar el nombre alternativo del sujeto.

Si no coloca los nombres DNS en la SAN, el certificado no se validará en un navegador y otros agentes de usuario que sigan las pautas de CA / Foro de navegadores.

Relacionado: los navegadores siguen las políticas de CA / Browser Forum; y no las políticas del IETF. Esa es una de las razones por las que un certificado creado con OpenSSL (que generalmente sigue el IETF) a veces no se valida en un navegador (los navegadores siguen la CA / B). Son estándares diferentes, tienen diferentes políticas de emisión y diferentes requisitos de validación.


Cree un certificado autofirmado (observe la -x509opción agregada):

openssl req -config example-com.conf -new -x509 -sha256 -newkey rsa:2048 -nodes \
    -keyout example-com.key.pem -days 365 -out example-com.cert.pem

Cree una solicitud de firma (observe la falta de -x509opción):

openssl req -config example-com.conf -new -sha256 -newkey rsa:2048 -nodes \
    -keyout example-com.key.pem -days 365 -out example-com.req.pem

Imprima un certificado autofirmado :

openssl x509 -in example-com.cert.pem -text -noout

Imprima una solicitud de firma :

openssl req -in example-com.req.pem -text -noout

Archivo de configuración (pasado a través de la -configopción)

[ req ]
default_bits        = 2048
default_keyfile     = server-key.pem
distinguished_name  = subject
req_extensions      = req_ext
x509_extensions     = x509_ext
string_mask         = utf8only

# The Subject DN can be formed using X501 or RFC 4514 (see RFC 4519 for a description).
#   Its sort of a mashup. For example, RFC 4514 does not provide emailAddress.
[ subject ]
countryName         = Country Name (2 letter code)
countryName_default     = US

stateOrProvinceName     = State or Province Name (full name)
stateOrProvinceName_default = NY

localityName            = Locality Name (eg, city)
localityName_default        = New York

organizationName         = Organization Name (eg, company)
organizationName_default    = Example, LLC

# Use a friendly name here because it's presented to the user. The server's DNS
#   names are placed in Subject Alternate Names. Plus, DNS names here is deprecated
#   by both IETF and CA/Browser Forums. If you place a DNS name here, then you
#   must include the DNS name in the SAN too (otherwise, Chrome and others that
#   strictly follow the CA/Browser Baseline Requirements will fail).
commonName          = Common Name (e.g. server FQDN or YOUR name)
commonName_default      = Example Company

emailAddress            = Email Address
emailAddress_default        = [email protected]

# Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...
[ x509_ext ]

subjectKeyIdentifier        = hash
authorityKeyIdentifier    = keyid,issuer

# You only need digitalSignature below. *If* you don't allow
#   RSA Key transport (i.e., you use ephemeral cipher suites), then
#   omit keyEncipherment because that's key transport.
basicConstraints        = CA:FALSE
keyUsage            = digitalSignature, keyEncipherment
subjectAltName          = @alternate_names
nsComment           = "OpenSSL Generated Certificate"

# RFC 5280, Section 4.2.1.12 makes EKU optional
#   CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
#   In either case, you probably only need serverAuth.
# extendedKeyUsage    = serverAuth, clientAuth

# Section req_ext is used when generating a certificate signing request. I.e., openssl req ...
[ req_ext ]

subjectKeyIdentifier        = hash

basicConstraints        = CA:FALSE
keyUsage            = digitalSignature, keyEncipherment
subjectAltName          = @alternate_names
nsComment           = "OpenSSL Generated Certificate"

# RFC 5280, Section 4.2.1.12 makes EKU optional
#   CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
#   In either case, you probably only need serverAuth.
# extendedKeyUsage    = serverAuth, clientAuth

[ alternate_names ]

DNS.1       = example.com
DNS.2       = www.example.com
DNS.3       = mail.example.com
DNS.4       = ftp.example.com

# Add these if you need them. But usually you don't want them or
#   need them in production. You may need them for development.
# DNS.5       = localhost
# DNS.6       = localhost.localdomain
# DNS.7       = 127.0.0.1

# IPv6 localhost
# DNS.8     = ::1

Es posible que deba 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 un CN en este caso.

# IPv4 localhost
# IP.1       = 127.0.0.1

# IPv6 localhost
# IP.2     = ::1

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

Se enumeran RFC 6797 y RFC 7469, porque son más restrictivas que las otras RFC y documentos CA / B. Las RFC 6797 y 7469 tampoco permiten una dirección IP.

8
  • 4
    ¿Es posible utilizar comodines en la alternate_namessección? Particularmente sub-subdominios. Tengo una pregunta que hace referencia a esta respuesta aquí: serverfault.com/questions/711596/… 12/08/15 a las 10:02
  • 3
    Acabo de responder a su pregunta específica. Creo que no tiene sentido agregar esta descripción de seguridad larga cuando la respuesta fue tan simple 21 de febrero de 2016 a las 1:44
  • 17
    @diegows: su respuesta no está completa ni es correcta. La razón por la que no es correcta se discute en la publicación larga que no desea leer :)
    jww
    21 de febrero de 2016 a las 4:42
  • 1
    ¡Gracias! Encontré tu publicación muy útil. Para su información, recientemente estuve jugando con la bóveda y descubrí que insistía en IP.x 127.0.0.1 en lugar de DNS.x 127 ... No verifiqué si esto está en el estándar o no.
    Chomeh
    22 de agosto de 2016 a las 0:32
  • 4
    Gracias @jww. Dijo, "1. Cree su propia autoridad (es decir, conviértase en una CA)" , luego dijo, "5. Instale el certificado de CA en el cliente" . Si la clave raíz se vio comprometida, una persona malintencionada podría firmar un certificado para cualquier dominio con esa clave, y si lo engañan para que vaya a su sitio web, ahora pueden realizar un ataque de intermediario. ¿Hay alguna forma de crear la CA raíz de modo que solo pueda firmar CA intermediarias y no certificados? Entonces puede proteger su CA intermediaria con una restricción de nombre. 30 de marzo de 2017 a las 18:41
476

A partir de 2021 con OpenSSL ≥ 1.1.1, el siguiente comando satisface todas sus necesidades, incluida SAN:

openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
  -keyout example.key -out example.crt -subj "/CN=example.com" \
  -addext "subjectAltName=DNS:example.com,DNS:www.example.net,IP:10.0.0.1"

En sistemas antiguos con OpenSSL ≤ 1.1.0, como Debian ≤ 9 o CentOS ≤ 7, es necesario utilizar una versión más larga de este comando:

openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
  -keyout example.key -out example.crt -extensions san -config \
  <(echo "[req]"; 
    echo distinguished_name=req; 
    echo "[san]"; 
    echo subjectAltName=DNS:example.com,DNS:www.example.net,IP:10.0.0.1
    ) \
  -subj "/CN=example.com"

Cualquiera de los dos comandos crea un certificado que es

  • válido para los (sub) dominios example.comy www.example.net(SAN),
  • también válido para la dirección IP 10.0.0.1(SAN),
  • relativamente fuerte (a partir de 2021) y
  • válido por 3650días (~ 10 años).

Se generan los siguientes archivos:

  • Llave privada: example.key
  • Certificado: example.crt

Toda la información se proporciona en la línea de comandos. No hay ninguna entrada interactiva que te moleste. No hay archivos de configuración con los que tengas que jugar. Todos los pasos necesarios se ejecutan mediante una única invocación de OpenSSL : desde la generación de la clave privada hasta el certificado autofirmado.

Observación n. ° 1: parámetros criptográficos

Dado que el certificado está autofirmado y los usuarios deben aceptarlo manualmente, no tiene sentido utilizar una caducidad corta o una criptografía débil.

En el futuro, es posible que desee usar más que 4096bits para la clave RSA y un algoritmo hash más fuerte que sha256, pero a partir de 2021, estos son valores cuerdos. Son lo suficientemente fuertes a la vez que son compatibles con todos los navegadores modernos.

Observación n. ° 2: parámetro " -nodes"

En teoría, podría omitir el -nodesparámetro (que significa "sin cifrado DES"), en cuyo caso example.keyse cifraría con una contraseña. Sin embargo, esto casi nunca es útil para la instalación de un servidor, porque también tendría que almacenar la contraseña en el servidor, o tendría que ingresarla manualmente en cada reinicio.

Observación n. ° 3: ver también

26
  • 2
    Intenté usar el oneliner # 2 (moderno) en Windows en mingw64, y enfrenté un error con el parámetro -subj. `$ openssl req -x509 -newkey rsa: 4096 -sha256 -days 3650 -nodes -keyout localhost.key -out localhost.crt -subj '/ CN = localhost' -addext subjectAltName = DNS: localhost, IP: 127.0.0.1 Generando una clave privada RSA que [...] escribe una nueva clave privada en 'localhost.key' ----- se espera que el nombre tenga el formato / type0 = value0 / type1 = value1 / type2 = ... donde los caracteres pueden ser escapado por \. Este nombre no está en ese formato: 'C: / Archivos de programa / Git / CN = localhost' problemas al realizar la solicitud de certificado ` 23/12/18 a las 14:12
  • 2
    No pude averiguar qué era exactamente el culpable en arg / CN = localhost expandiéndose a C: / Program Files / Git / CN = localhost, así que ejecuté todo el comando en cmd.exe simple y funcionó bien. En caso de que alguien esté luchando con este. 23/12/18 a las 14:15
  • 1
    @FranklinYu ¿Estás seguro de que rsa: 2048 será suficiente en 10 años a partir de ahora? Porque ese es el período de validez. Como se explicó, no tiene sentido usar una caducidad corta o una criptografía débil. La mayoría de las claves RSA de 2048 bits tienen un período de validez de 1 a 3 años como máximo. Con respecto a OpenSSL 1.1.1, todavía dejo sha256 allí, por lo que es más explícito y obvio cambiar si desea un hash más fuerte.
    vog
    12/01/19 a las 20:18
  • 19
    1000 + 1s para crear un "one-liner" que use la nueva SAN requerida sin tener que crear un archivo de configuración extenso con mucho texto repetitivo. ¡Bien hecho! 23 de septiembre de 2019 a las 3:35
  • 2
    A partir del 31 de agosto de 2020, puedo dar fe de que esto funciona. ¡Muchas gracias! Realmente me gustaría ver una referencia que explique en términos simples por qué esto está evolucionando a tal ritmo. Una parte de mí se pregunta si es solo porque la idea de crear certificados autofirmados es contraproducente para las grandes empresas tecnológicas. ¿Qué se necesitará dentro de 10 o 20 años? Es una locura, y es un testimonio de la cantidad de actividad que genera este tipo de preguntas en openssl. 1 de septiembre de 2020 a las 2:51
434

Aquí están las opciones descritas en la respuesta de @ diegows , descritas con más detalle, de la documentación :

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX
req

PKCS#10 certificate request and certificate generating utility.

-x509

this option outputs a self signed certificate instead of a certificate request. This is typically used to generate a test certificate or a self signed root CA.

-newkey arg

this option creates a new certificate request and a new private key. The argument takes one of several forms. rsa:nbits, where nbits is the number of bits, generates an RSA key nbits in size.

-keyout filename

this gives the filename to write the newly created private key to.

-out filename

This specifies the output filename to write to or standard output by default.

-days n

when the -x509 option is being used this specifies the number of days to certify the certificate for. The default is 30 days.

-nodes

if this option is specified then if a private key is created it will not be encrypted.

En realidad, la documentación es más detallada que la anterior; Lo resumí aquí.

2
164

No puedo comentar, así que pondré esto como una respuesta separada. Encontré algunos problemas con la respuesta de una sola línea aceptada:

  • El one-liner incluye una frase de contraseña en la clave.
  • El one-liner usa SHA-1 que en muchos navegadores arroja advertencias en la consola.

Aquí hay una versión simplificada que elimina la frase de contraseña, aumenta la seguridad para suprimir las advertencias e incluye una sugerencia en los comentarios para pasar -subj para eliminar la lista completa de preguntas:

openssl genrsa -out server.key 2048
openssl rsa -in server.key -out server.key
openssl req -sha256 -new -key server.key -out server.csr -subj '/CN=localhost'
openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt

Reemplace 'localhost' con cualquier dominio que necesite. Deberá ejecutar los dos primeros comandos uno por uno, ya que OpenSSL le solicitará una frase de contraseña.

Para combinar los dos en un archivo .pem:

cat server.crt server.key > cert.pem
10
  • 7
    Necesitaba un certificado de desarrollo para github.com/molnarg/node-http2 y esta respuesta es la mejor.
    Capaj
    8 de noviembre de 2015 a las 11:09
  • 1
    Para combinar el certificado y la clave en un solo archivo: cat server.crt server.key >foo-cert.pem. Funciona con el ejemplo enopenssl-1.0.2d/demos/ssl/ 9/11/15 a las 12:33
  • El certificado que generé de esta manera todavía usa SHA1. 7 de ene. De 2016 a las 14:58
  • 1
    Tks, funciona muy bien para crear un certificado autofirmado FreeBSD 10 OpenLDAP 2.4conTLS 3 oct 2016 a las 20:34
  • 3
    ¿Qué pasa con el archivo key.pem? 17/11/2016 a las 10:24
79

Los navegadores modernos ahora arrojan un error de seguridad para los certificados autofirmados bien formados si les falta un SAN (nombre alternativo del sujeto). OpenSSL no proporciona una forma de línea de comandos para especificar esto , por lo que los tutoriales y marcadores de muchos desarrolladores de repente quedan obsoletos.

La forma más rápida de volver a ejecutar es un archivo de configuración breve e independiente:

  1. Crear un archivo de configuración de OpenSSL (ejemplo: req.cnf)

    [req]
    distinguished_name = req_distinguished_name
    x509_extensions = v3_req
    prompt = no
    [req_distinguished_name]
    C = US
    ST = VA
    L = SomeCity
    O = MyCompany
    OU = MyDivision
    CN = www.company.com
    [v3_req]
    keyUsage = critical, digitalSignature, keyAgreement
    extendedKeyUsage = serverAuth
    subjectAltName = @alt_names
    [alt_names]
    DNS.1 = www.company.com
    DNS.2 = company.com
    DNS.3 = company.net
    
  2. Cree el certificado que hace referencia a este archivo de configuración

    openssl req -x509 -nodes -days 730 -newkey rsa:2048 \
     -keyout cert.key -out cert.pem -config req.cnf -sha256
    

Configuración de ejemplo de https://support.citrix.com/article/CTX135602

10
  • 1
    Me funcionó después de eliminar el último parámetro -extensiones 'v3_req' que estaba causando un error. Usando OpenSSL para Windows. ¡Finalmente, me las arreglo para solucionar este problema! Gracias.
    CGodo
    10 de mayo de 2017 a las 18:25
  • 1
    @Kyopaxa tiene razón: ese parámetro es redundante con la línea 3 del archivo cnf; actualizado.
    rymo
    10 de mayo de 2017 a las 21:23
  • 2
    Forma sólida. Gracias. Sugeriría agregar -sha256. 27/07/2017 a las 10:13
  • 5
    Ahora puede especificar la SAN en la línea de comando con -extension 'subjectAltName = DNS:dom.ain, DNS:oth.er'ver github.com/openssl/openssl/pull/4986 23/01/18 a las 11:02
  • 3
    Parece que esta opción se llama -addextahora. 20/11/18 a las 14:10
70

Recomendaría agregar el parámetro -sha256 , para usar el algoritmo hash SHA-2, porque los principales navegadores están considerando mostrar los "certificados SHA-1" como no seguros.

La misma línea de comando de la respuesta aceptada: @diegows con -sha256 agregado

openssl req -x509 -sha256 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX

Más información en el blog de seguridad de Google .

Actualización de mayo de 2018. Como muchos señalaron en los comentarios, el uso de SHA-2 no agrega ninguna seguridad a un certificado autofirmado. Pero todavía recomiendo usarlo como un buen hábito de no usar funciones de hash criptográficas desactualizadas / inseguras. La explicación completa está disponible en ¿Por qué está bien que los certificados superiores al certificado de entidad final estén basados ​​en SHA-1? .

11
  • 1
    Si es una clave autofirmada, generará errores en el navegador de todos modos, por lo que esto realmente no importa.
    Mark
    16/12/14 a las 13:43
  • 31
    @Mark, importa, porque SHA-2 es más seguro 17 de diciembre de 2014 a las 15:38
  • 1
    Al abrir el certificado en Windows después de cambiar el nombre de cert.pem a cert.cer, el algoritmo de huellas digitales sigue siendo Sha1, pero el algoritmo de hash de firma es sha256.
    sinned
    19 de diciembre de 2014 a las 8:33
  • 2
    "Cifrado de clase mundial * autenticación cero = seguridad cero" gerv.net/security/self-signed-certs
    x-yuri
    29 de marzo de 2018 a las 9:03
  • 4
    Tenga en cuenta que el algoritmo de firma utilizado en un certificado autofirmado es irrelevante para decidir si es confiable o no. Los certificados de CA raíz están autofirmados. y en mayo de 2018, todavía hay muchos certificados de CA raíz activos que están firmados por SHA-1. Porque no importa si un certificado confía en sí mismo, ni cómo ese certificado verifica esa confianza. O confía en el certificado raíz / autofirmado por lo que dice que es, o no lo hace. Consulte security.stackexchange.com/questions/91913/… 8 de mayo de 2018 a las 18:55
22

Este es el script que utilizo en las cajas locales para configurar la SAN (subjectAltName) en certificados autofirmados.

Este script toma el nombre de dominio (example.com) y genera la SAN para * .example.com y example.com en el mismo certificado. Se comentan las secciones siguientes. Nombra el script (por ejemplo generate-ssl.sh) y dale permisos de ejecución. Los archivos se escribirán en el mismo directorio que el script.

Chrome 58 y posteriores requiere que SAN se establezca en certificados autofirmados.

#!/usr/bin/env bash

# Set the TLD domain we want to use
BASE_DOMAIN="example.com"

# Days for the cert to live
DAYS=1095

# A blank passphrase
PASSPHRASE=""

# Generated configuration file
CONFIG_FILE="config.txt"

cat > $CONFIG_FILE <<-EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
x509_extensions = v3_req
distinguished_name = dn

[dn]
C = CA
ST = BC
L = Vancouver
O = Example Corp
OU = Testing Domain
emailAddress = [email protected]$BASE_DOMAIN
CN = $BASE_DOMAIN

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.$BASE_DOMAIN
DNS.2 = $BASE_DOMAIN
EOF

# The file name can be anything
FILE_NAME="$BASE_DOMAIN"

# Remove previous keys
echo "Removing existing certs like $FILE_NAME.*"
chmod 770 $FILE_NAME.*
rm $FILE_NAME.*

echo "Generating certs for $BASE_DOMAIN"

# Generate our Private Key, CSR and Certificate
# Use SHA-2 as SHA-1 is unsupported from Jan 1, 2017

openssl req -new -x509 -newkey rsa:2048 -sha256 -nodes -keyout "$FILE_NAME.key" -days $DAYS -out "$FILE_NAME.crt" -passin pass:$PASSPHRASE -config "$CONFIG_FILE"

# OPTIONAL - write an info to see the details of the generated crt
openssl x509 -noout -fingerprint -text < "$FILE_NAME.crt" > "$FILE_NAME.info"

# Protect the key
chmod 400 "$FILE_NAME.key"

Esta secuencia de comandos también escribe un archivo de información, por lo que puede inspeccionar el nuevo certificado y verificar que la SAN esté configurada correctamente.

                ...
                28:dd:b8:1e:34:b5:b1:44:1a:60:6d:e3:3c:5a:c4:
                da:3d
            Exponent: 65537 (0x10001)
    X509v3 extensions:
        X509v3 Subject Alternative Name: 
            DNS:*.example.com, DNS:example.com
Signature Algorithm: sha256WithRSAEncryption
     3b:35:5a:d6:9e:92:4f:fc:f4:f4:87:78:cd:c7:8d:cd:8c:cc:
     ...

Si está utilizando Apache, puede hacer referencia al certificado anterior en su archivo de configuración así:

<VirtualHost _default_:443>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/htdocs

    SSLEngine on
    SSLCertificateFile path/to/your/example.com.crt
    SSLCertificateKeyFile path/to/your/example.com.key
</VirtualHost>

Recuerde reiniciar su servidor Apache (o Nginx, o IIS) para que surta efecto el nuevo certificado.

3
  • Funciona en macOS High Siera y Chrome 58 23 dic 2017 a las 11:58
  • ¿Todavía no estoy seguro de cómo afecta el CN ​​a la configuración general? Estoy intentando ejecutar esto como localhosto 127.0.0.1:port#cuál sería el correspondiente CNpara algo como esto.
    DJ2
    16/04/18 a las 16:56
  • @ DJ2 Yo establecería BASE_DOMAIN = "localhost"
    Drakes
    16/04/18 a las 23:11
16

No puedo comentar, así que agrego una respuesta por separado. Intenté crear un certificado autofirmado para NGINX y fue fácil, pero cuando quise agregarlo a la lista blanca de Chrome tuve un problema. Y mi solución fue crear un certificado raíz y firmar un certificado secundario con él.

Así que paso a paso. Crear archivo config_ssl_ca.cnf Aviso, el archivo de configuración tiene una opción basicConstraints = CA: true, lo que significa que se supone que este certificado es raíz.

This is a good practice, because you create it once and can reuse.

[ req ]
default_bits = 2048

prompt = no
distinguished_name=req_distinguished_name
req_extensions = v3_req

[ req_distinguished_name ]
countryName=UA
stateOrProvinceName=root region
localityName=root city
organizationName=Market(localhost)
organizationalUnitName=roote department
commonName=market.localhost
[email protected]

[ alternate_names ]
DNS.1        = market.localhost
DNS.2        = www.market.localhost
DNS.3        = mail.market.localhost
DNS.4        = ftp.market.localhost
DNS.5        = *.market.localhost

[ v3_req ]
keyUsage=digitalSignature
basicConstraints=CA:true
subjectKeyIdentifier = hash
subjectAltName = @alternate_names

El siguiente archivo de configuración para su certificado secundario se llamará config_ssl.cnf .

[ req ]
default_bits = 2048

prompt = no
distinguished_name=req_distinguished_name
req_extensions = v3_req

[ req_distinguished_name ]
countryName=UA
stateOrProvinceName=Kyiv region
localityName=Kyiv
organizationName=market place
organizationalUnitName=market place department
commonName=market.localhost
[email protected]

[ alternate_names ]
DNS.1        = market.localhost
DNS.2        = www.market.localhost
DNS.3        = mail.market.localhost
DNS.4        = ftp.market.localhost
DNS.5        = *.market.localhost

[ v3_req ]
keyUsage=digitalSignature
basicConstraints=CA:false
subjectAltName = @alternate_names
subjectKeyIdentifier = hash

El primer paso: crear una clave raíz y un certificado

openssl genrsa -out ca.key 2048
openssl req -new -x509 -key ca.key -out ca.crt -days 365 -config config_ssl_ca.cnf

El segundo paso crea la clave secundaria y el archivo CSR - Solicitud de firma de certificado. Porque la idea es firmar el certificado hijo por root y obtener un certificado correcto

openssl genrsa -out market.key 2048
openssl req -new -sha256 -key market.key -config config_ssl.cnf -out market.csr

Abra la terminal de Linux y haga este comando

echo 00 > ca.srl
touch index.txt

El archivo de texto ca.srl que contiene el siguiente número de serie para usar en hexadecimal. Obligatorio. Este archivo debe estar presente y contener un número de serie válido.

Último paso, cree un archivo de configuración más y llámelo config_ca.cnf

# we use 'ca' as the default section because we're usign the ca command
[ ca ]
default_ca = my_ca

[ my_ca ]
#  a text file containing the next serial number to use in hex. Mandatory.
#  This file must be present and contain a valid serial number.
serial = ./ca.srl

# the text database file to use. Mandatory. This file must be present though
# initially it will be empty.
database = ./index.txt

# specifies the directory where new certificates will be placed. Mandatory.
new_certs_dir = ./

# the file containing the CA certificate. Mandatory
certificate = ./ca.crt

# the file contaning the CA private key. Mandatory
private_key = ./ca.key

# the message digest algorithm. Remember to not use MD5
default_md = sha256

# for how many days will the signed certificate be valid
default_days = 365

# a section with a set of variables corresponding to DN fields
policy = my_policy

# MOST IMPORTANT PART OF THIS CONFIG
copy_extensions = copy

[ my_policy ]
# if the value is "match" then the field value must match the same field in the
# CA certificate. If the value is "supplied" then it must be present.
# Optional means it may be present. Any fields not mentioned are silently
# deleted.
countryName = match
stateOrProvinceName = supplied
organizationName = supplied
commonName = market.localhost
organizationalUnitName = optional
commonName = supplied

Puede preguntar, por qué es tan difícil, por qué debemos crear una configuración más para firmar el certificado secundario por root. La respuesta es simple porque el certificado secundario debe tener un bloque SAN: nombres alternativos del sujeto. Si firmamos el certificado secundario con las utilidades "openssl x509", el certificado raíz eliminará el campo SAN en el certificado secundario. Entonces usamos "openssl ca" en lugar de "openssl x509" para evitar la eliminación del campo SAN. Creamos un nuevo archivo de configuración y le decimos que copie todos los campos extendidos copy_extensions = copy .

openssl ca -config config_ca.cnf -out market.crt -in market.csr

El programa te hace 2 preguntas:

  1. ¿Firmar el certificado? Di "Y"
  2. 1 de cada 1 solicitud de certificado certificada, ¿confirma? Di "Y"

En la terminal puedes ver una oración con la palabra "Base de datos", significa archivo index.txt que creas con el comando "touch". Contendrá toda la información de todos los certificados que cree con la utilidad "openssl ca". Para comprobar el uso válido del certificado:

openssl rsa -in market.key -check

Si quieres ver qué hay dentro de CRT:

openssl x509 -in market.crt -text -noout

Si quieres ver qué hay dentro de CSR:

openssl req -in market.csr -noout -text 
4
  • 2
    Aunque este proceso parece complicado, esto es exactamente lo que necesitamos para el dominio .dev, ya que este dominio no admite certificados autofirmados y Chrome y Firefox están forzando HSTS. Lo que hice fue seguir estos pasos, que es crear CA, crear un certificado y firmarlo con mi CA y al final confiar en mi CA en el navegador. Gracias. 17 abr.20 a las 23:08
  • 1
    Tu nombre común es incorrecto. No nombre / apellido. es su dominio cn, es decir, www.yoursite.com. ver ssl.com/faqs/common-name 16 de agosto de 2020 a las 8:54
  • 1
    No hay problema. Hay algunos documentos que también dicen nombre (su nombre), lo cual es un poco engañoso. pero el nombre común debe ser el dominio real. en este sentido sería (su nombre de "dominio") lo que están tratando de decir. cuando se ejecuta con el método interactivo para crear los certificados, dice cn = domain example. así que commonname debería ser dominio 19/08/20 a las 9:20
  • Respuesta UPD para resolver stackoverflow.com/questions/39270992/…
    mrkiril
    26 oct.20 a las 14:37
9

2017 de una sola línea:

openssl req \
-newkey rsa:2048 \
-x509 \
-nodes \
-keyout server.pem \
-new \
-out server.pem \
-subj /CN=localhost \
-reqexts SAN \
-extensions SAN \
-config <(cat /System/Library/OpenSSL/openssl.cnf \
    <(printf '[SAN]\nsubjectAltName=DNS:localhost')) \
-sha256 \
-days 3650

Esto también funciona en Chrome 57, ya que proporciona la SAN, sin tener otro archivo de configuración. Fue tomado de una respuesta aquí .

Esto crea un único archivo .pem que contiene tanto la clave privada como el certificado. Puede moverlos a archivos .pem separados si es necesario.

2
  • 2
    Para los usuarios de Linux, deberá cambiar esa ruta para el archivo config. por ejemplo, en las /etc/ssl/openssl.confobras actuales de Ubuntu 27/09/18 a las 10:53
  • Para una sola línea que no requiere que especifique la ubicación de openssl.cnf, consulte: stackoverflow.com/a/41366949/19163
    vog
    26 nov 2018 a las 9:56
8

Versión de una sola línea 2017:

CentOS:

openssl req -x509 -nodes -sha256 -newkey rsa:2048 \
-keyout localhost.key -out localhost.crt \
-days 3650 \
-subj "CN=localhost" \
-reqexts SAN -extensions SAN \
-config <(cat /etc/pki/tls/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=IP:127.0.0.1,DNS:localhost"))

Ubuntu:

openssl req -x509 -nodes -sha256 -newkey rsa:2048 \
-keyout localhost.key -out localhost.crt \
-days 3650 \
-subj "/CN=localhost" \
-reqexts SAN -extensions SAN \
-config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=IP:127.0.0.1,DNS:localhost"))

Editar: se agregó la opción Slash anterior a 'subj' para Ubuntu.

6

Tiene el procedimiento general correcto. La sintaxis del comando se encuentra a continuación.

openssl req -new -key {private key file} -out {output file}

Sin embargo, se muestran las advertencias porque el navegador no pudo verificar la identidad al validar el certificado con una autoridad certificadora (CA) conocida.

Como se trata de un certificado autofirmado, no existe una CA y puede ignorar la advertencia y continuar. Si desea obtener un certificado real que sea reconocible por cualquier persona en la Internet pública, el procedimiento se detalla a continuación.

  1. Genera una clave privada
  2. Use esa clave privada para crear un archivo CSR
  3. Envíe CSR a CA (Verisign u otros, etc.)
  4. Instale el certificado recibido de CA en el servidor web
  5. Agregue otros certificados a la cadena de autenticación según el tipo de certificado

Tengo más detalles sobre esto en una publicación en Securing the Connection: Creando un certificado de seguridad con OpenSSL

0
6

Un revestimiento FTW. Me gusta mantenerlo simple. ¿Por qué no utilizar un comando que contenga TODOS los argumentos necesarios? Así es como me gusta: esto crea un certificado x509 y su clave PEM:

openssl req -x509 \
 -nodes -days 365 -newkey rsa:4096 \
 -keyout self.key.pem \
 -out self-x509.crt \
 -subj "/C=US/ST=WA/L=Seattle/CN=example.com/[email protected]"

Ese único comando contiene todas las respuestas que normalmente proporcionaría para los detalles del certificado. De esta manera, puede configurar los parámetros y ejecutar el comando, obtener su salida y luego ir a tomar un café.

>> Más aquí <<

1
  • 1
    Todos los argumentos, excepto los SAN ... la respuesta de @ vog también cubre eso (y es anterior a esto) (Sin embargo, este tiene un campo de "Asunto" más completo completado ...) (Tampoco es un gran fanático del vencimiento de un año) 18/12/18 a las 10:38
5

Generate keys

I am using /etc/mysql for cert storage because /etc/apparmor.d/usr.sbin.mysqld contains /etc/mysql/*.pem r.

sudo su -
cd /etc/mysql
openssl genrsa -out ca-key.pem 2048;
openssl req -new -x509 -nodes -days 1000 -key ca-key.pem -out ca-cert.pem;
openssl req -newkey rsa:2048 -days 1000 -nodes -keyout server-key.pem -out server-req.pem;
openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem;
openssl req -newkey rsa:2048 -days 1000 -nodes -keyout client-key.pem -out client-req.pem;
openssl x509 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem;

Add configuration

/etc/mysql/my.cnf

[client]
ssl-ca=/etc/mysql/ca-cert.pem
ssl-cert=/etc/mysql/client-cert.pem
ssl-key=/etc/mysql/client-key.pem

[mysqld]
ssl-ca=/etc/mysql/ca-cert.pem
ssl-cert=/etc/mysql/server-cert.pem
ssl-key=/etc/mysql/server-key.pem

En mi configuración, el servidor Ubuntu inició sesión en: /var/log/mysql/error.log

Notas de seguimiento:

  • SSL error: Unable to get certificate from '...'

    Es posible que a MySQL se le niegue el acceso de lectura a su archivo de certificado si no está en la configuración de apariencia . Como se mencionó en los pasos anteriores ^, guarde todos nuestros certificados como .pemarchivos en el /etc/mysql/directorio que está aprobado por defecto por apparmor (o modifique su apparmor / SELinux para permitir el acceso a donde los haya almacenado).

  • SSL error: Unable to get private key

    Es posible que la versión de su servidor MySQL no admita el rsa:2048formato predeterminado

    Convierta lo generado rsa:2048a simple rsacon:

    openssl rsa -in server-key.pem -out server-key.pem
    openssl rsa -in client-key.pem -out client-key.pem
    
  • Compruebe si el servidor local admite SSL :

    mysql -u root -p
    mysql> show variables like "%ssl%";
    +---------------+----------------------------+
    | Variable_name | Value                      |
    +---------------+----------------------------+
    | have_openssl  | YES                        |
    | have_ssl      | YES                        |
    | ssl_ca        | /etc/mysql/ca-cert.pem     |
    | ssl_capath    |                            |
    | ssl_cert      | /etc/mysql/server-cert.pem |
    | ssl_cipher    |                            |
    | ssl_key       | /etc/mysql/server-key.pem  |
    +---------------+----------------------------+
    
  • Verificar que una conexión a la base de datos esté encriptada con SSL :

    Verifying connection

    When logged in to the MySQL instance, you can issue the query:

    show status like 'Ssl_cipher';
    

    If your connection is not encrypted, the result will be blank:

    mysql> show status like 'Ssl_cipher';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | Ssl_cipher    |       |
    +---------------+-------+
    1 row in set (0.00 sec)
    

    Otherwise, it would show a non-zero length string for the cypher in use:

    mysql> show status like 'Ssl_cipher';
    +---------------+--------------------+
    | Variable_name | Value              |
    +---------------+--------------------+
    | Ssl_cipher    | DHE-RSA-AES256-SHA |
    +---------------+--------------------+
    1 row in set (0.00 sec)
    
  • Requerir ssl para la conexión de un usuario específico ('requerir ssl'):

    • SSL

    Tells the server to permit only SSL-encrypted connections for the account.

    GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
      REQUIRE SSL;
    

    To connect, the client must specify the --ssl-ca option to authenticate the server certificate, and may additionally specify the --ssl-key and --ssl-cert options. If neither --ssl-ca option nor --ssl-capath option is specified, the client does not authenticate the server certificate.


Enlace alternativo: tutorial extenso sobre conexiones seguras de PHP a MySQL con SSL .

2
  • -1; esto es en gran parte tangencial a la pregunta formulada, y también hace un mal trabajo al aclarar de dónde provienen sus citas. 29/09/19 a las 17:12
  • Esto muestra los certificados de CA de aprovisionamiento, servidor / cliente firmados por la CA, configúrelos para que los lea mysqld en un host con apparmor. Ejemplifica un caso bastante inútil de alojar el ca, el servidor y el cliente en la misma máquina, y exponer peligrosamente la autoridad de ese ca al proceso mysqld. Esta configuración realmente no tiene sentido más que para probar la configuración ssl en un entorno de prueba. Para operar una CA interna, recomendaría la cadena de herramientas gnuttls en lugar de openssl help.ubuntu.com/community/GnuTLS y tener una buena comprensión de tls antes de trabajar en el caso mysqld + apparmor 29/09/19 a las 20:57
4

Como se ha discutido en detalle, los certificados autofirmados no son confiables para Internet . Puede agregar su certificado autofirmado a muchos navegadores, pero no a todos . Alternativamente, puede convertirse en su propia autoridad certificadora .

La razón principal por la que uno no desea obtener un certificado firmado de una autoridad de certificación es el costo: Symantec cobra entre $ 995 y $ 1,999 por año por certificados; solo por un certificado destinado a la red interna, Symantec cobra $ 399 por año . Ese costo es fácil de justificar si está procesando pagos con tarjeta de crédito o si trabaja para el centro de ganancias de una empresa altamente rentable. Es más de lo que muchos pueden permitirse para un proyecto personal que uno está creando en Internet, o para una organización sin fines de lucro que se ejecuta con un presupuesto mínimo, o si uno trabaja en un centro de costos de una organización; los centros de costos siempre intentan hacer más con menos.

Una alternativa es usar certbot (ver sobre certbot ). Certbot es un cliente automático fácil de usar que obtiene e implementa certificados SSL / TLS para su servidor web.

Si configura certbot, puede habilitarlo para crear y mantener un certificado emitido por la autoridad de certificación de Let's Encrypt .

Hice esto durante el fin de semana para mi organización. Instalé los paquetes requeridos para certbot en mi servidor (Ubuntu 16.04) y luego ejecuté el comando necesario para configurar y habilitar certbot. Es probable que uno necesite un complemento de DNS para certbot; actualmente estamos usando DigitalOcean, aunque es posible que pronto migremos a otro servicio.

Tenga en cuenta que algunas de las instrucciones no eran del todo correctas y tomó un poco de tiempo con Google para averiguarlo. Esto tomó una buena cantidad de mi tiempo la primera vez, pero ahora creo que podría hacerlo en minutos.

Para DigitalOcean, un área en la que luché fue cuando se me pidió que ingresara la ruta a su archivo INI de credenciales de DigitalOcean. A lo que se refiere el script es a la página Aplicaciones y API y a la pestaña Tokens / Clave en esa página. Debe tener o generar un token de acceso personal (lectura y escritura) para la API de DigitalOcean; esta es una cadena hexadecimal de 65 caracteres. Esta cadena luego debe colocarse en un archivo en el servidor web desde el cual está ejecutando certbot. Ese archivo puede tener un comentario como primera línea (los comentarios comienzan con #). La segunda línea es:

dns_digitalocean_token = 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff

Una vez que descubrí cómo configurar un token de lectura + escritura para la API de DigitalOcean, fue bastante fácil usar certbot para configurar un certificado comodín . Tenga en cuenta que no es necesario configurar un certificado comodín; en su lugar, se puede especificar cada dominio y subdominio al que se desea que se aplique el certificado. Era el certificado comodín que requería el archivo INI de credenciales que contenía el token de acceso personal de DigitalOcean.

Tenga en cuenta que los certificados de clave pública (también conocidos como certificados de identidad o certificados SSL) caducan y requieren renovación. Por lo tanto, deberá renovar su certificado de forma periódica (recurrente). La documentación del certbot cubre la renovación de certificados .

Mi plan es escribir un script para usar el comando openssl para obtener la fecha de vencimiento de mi certificado y activar la renovación cuando falten 30 días o menos hasta que venza. Luego agregaré este script a cron y lo ejecutaré una vez al día.

Aquí está el comando para leer la fecha de vencimiento de su certificado:

[email protected]:~# /usr/bin/openssl x509 -enddate -noout -in path-to-certificate-pem-file
notAfter=May 25 19:24:12 2019 GMT
2

opensslpermite generar un certificado autofirmado con un solo comando ( -newkey instruye a generar una clave privada e -x509instruye a emitir un certificado autofirmado en lugar de una solicitud de firma):

openssl req -x509 -newkey rsa:4096 \
-keyout my.key -passout pass:123456 -out my.crt \
-days 365 \
-subj /CN=localhost/O=home/C=US/[email protected] \
-addext "subjectAltName = DNS:localhost,DNS:web.internal,email:[email protected]" \
-addext keyUsage=digitalSignature -addext extendedKeyUsage=serverAuth

Puede generar una clave privada y construir un certificado autofirmado en pasos separados:

openssl genrsa -out my.key -passout pass:123456 2048

openssl req -x509 \
-key my.key -passin pass:123456 -out my.csr \
-days 3650 \
-subj /CN=localhost/O=home/C=US/[email protected] \
-addext "subjectAltName = DNS:localhost,DNS:web.internal,email:[email protected]" \
-addext keyUsage=digitalSignature -addext extendedKeyUsage=serverAuth

Revise el certificado resultante:

openssl x509 -text -noout -in my.crt

Java keytoolcrea la tienda PKCS # 12:

keytool -genkeypair -keystore my.p12 -alias master \
-storetype pkcs12 -keyalg RSA -keysize 2048 -validity 3650 \
-storepass 123456 \
-dname "CN=localhost,O=home,C=US" \
-ext 'san=dns:localhost,dns:web.internal,email:[email protected]'

Para exportar el certificado autofirmado:

keytool -exportcert -keystore my.p12 -file my.crt \
-alias master -rfc -storepass 123456

Revise el certificado resultante:

keytool -printcert -file my.crt

certtoolde GnuTLS no permite pasar diferentes atributos de CLI. No me gusta meterme con los archivos de configuración ((

2

esto funcionó para mí

openssl req -x509 -nodes -subj '/CN=localhost'  -newkey rsa:4096 -keyout ./sslcert/key.pem -out ./sslcert/cert.pem -days 365

server.js

var fs = require('fs');
var path = require('path');
var http = require('http');
var https = require('https');
var compression = require('compression');
var express = require('express');
var app = express();

app.use(compression());
app.use(express.static(__dirname + '/www'));    

app.get('/*', function(req,res) {
  res.sendFile(path.join(__dirname+'/www/index.html'));
});

// your express configuration here

var httpServer = http.createServer(app);
var credentials = {
    key: fs.readFileSync('./sslcert/key.pem', 'utf8'),
    cert: fs.readFileSync('./sslcert/cert.pem', 'utf8')
};
var httpsServer = https.createServer(credentials, app);

httpServer.listen(8080);
httpsServer.listen(8443);

console.log(`RUNNING ON  http://127.0.0.1:8080`);
console.log(`RUNNING ON  http://127.0.0.1:8443`);