Pregunta ¿Cómo crear un certificado autofirmado con openssl?


Estoy agregando soporte https a un dispositivo Linux incorporado. 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:

¡Probablemente este no sea el sitio que estás buscando!
  Certificado de seguridad del sitio no es de confianza!

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


854
2018-04-16 14:14


origen


Respuestas:


Puedes hacer eso en un comando:

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

También puedes agregar -nodes 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 parámetro días (365) puede reemplazarse con cualquier número para afectar la fecha de vencimiento. Luego, le solicitará cosas como "Nombre del país", pero puede presionar Entrar y aceptar valores predeterminados.

Añadir -subj '/CN=localhost' para suprimir preguntas sobre el contenido del certificado (reemplazar localhost con su dominio deseado)

Los certificados autofirmados no se validan con ningún tercero a menos que los importes previamente a los navegadores. Si necesita más seguridad, debe usar un certificado firmado por una CA.


1485
2018-04-16 15:04



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

Es fácil crear un certificado autofirmado. Solo usa el openssl req mando. Puede ser 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 Foros de CA / Browser (ver referencias a continuación). Las restricciones surgen en dos áreas clave: (1) anclajes de confianza y (2) nombres de DNS.

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

Algunos navegadores no hacen exactamente fácil importar un certificado de servidor autofirmado. De hecho, no puedes con algunos navegadores, como el navegador de Android. Entonces, la solución completa es convertirse en su propia autoridad.

En la ausencia de convertirse en su propia autoridad, debe obtener los nombres DNS correctos para dar al certificado la mayor posibilidad de éxito. Pero te animo a convertirte en tu propia autoridad. Es fácil convertirse en su propia autoridad y dará un paso al costado de todos los problemas de confianza (¿quién mejor para confiar que usted?).


¡Probablemente este no sea el sitio que estás buscando!
  Certificado de seguridad del sitio no es de confianza!

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

La mejor manera de evitar esto es:

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

Paso 1 - Crea tu propia autoridad solo significa crear un certificado autofirmado con CA: true y el uso correcto 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 keyCertSign y crlSign (si está utilizando CRL), y el Identificador de clave de sujeto (SKI) es el mismo que el Identificador de clave de autoridad (AKI).

Para convertirse en su propia autoridad de certificación, consulte ¿Cómo firmas la solicitud de firma de certificado con tu autoridad de certificación? en desbordamiento de pila. Luego, importe su CA en el Trust Store utilizado por el navegador.

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

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) no confiar en los certificados autofirmados va a ser un gran problema en Internet of Things (IoT). Por ejemplo, ¿qué va a pasar cuando te conectes a tu termostato o refrigerador 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. Ver, por ejemplo, Propuesta: marcar HTTP como no seguro.


¿Cómo crear un certificado autofirmado con openssl?

Los comandos a continuación y el archivo de configuración crean un certificado autofirmado (también le 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 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 comando). Luego hay un alternate_names sección en el archivo de configuración (debe ajustar esto para satisfacer 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
# DNS.7       = 127.0.0.1

# IPv6 localhost
# DNS.8     = ::1

Es importante poner el nombre DNS en la SAN y no en el CN ​​porque ambos el IETF y el CA / Browser Forums especifican la práctica. También especifican que los nombres DNS en el CN ​​están en desuso (pero no están prohibidos). Si pones un nombre DNS en el CN, luego debe ser incluido en la SAN bajo las políticas de CA / B. Por lo tanto, no puede evitar el uso del nombre alternativo del sujeto.

Si no lo hace, ponga nombres DNS en la SAN, entonces el certificado no podrá validar bajo un navegador y otros agentes de usuario que cumplan con los lineamientos del CA / Browser Forum.

Relacionado: los navegadores siguen las políticas de CA / Browser Forum; y no las políticas IETF. Esa es una de las razones por las que un certificado creado con OpenSSL (que generalmente sigue el IETF) a veces no valida bajo 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.


Crea un certificado autofirmado (observe la adición de -x509 opción):

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

Crear una solicitud de firma (fíjate en la falta de -x509 opció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

Imprimir una solicitud de firma:

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

Archivo de configuración (pasado a través de -config opció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 its 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        = test@example.com

# 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 otra manera Chrome puede quejarse Nombre común es invá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

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

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 no haga permitir una dirección IP, tampoco.


390
2018-01-13 21:12



Estas son las opciones descritas en la respuesta de @diegows, descrito con más detalle, desde la documentación:

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

PKCS # 10 solicitud de certificado y utilidad de generación de certificado.

-x509

esta opción genera un certificado autofirmado en lugar de una solicitud de certificado.   Esto normalmente se usa para generar un certificado de prueba o una CA raíz auto-firmada.

-newkey arg

esta opción crea una nueva solicitud de certificado y una nueva clave privada. El argumento   toma una de varias formas. rsa: nbits, dónde nbits es la cantidad de bits,   genera una clave RSA nbits en tamaño.

-keyout filename

esto le da el nombre de archivo para escribir la clave privada recién creada.

-out filename

Esto especifica el nombre de archivo de salida para escribir en o salida estándar por defecto.

-days n

cuando el -x509 se está utilizando la opción Esto especifica el número de días para certificar   el certificado para. El valor predeterminado es 30 días.

-nodes

si se especifica esta opción, si se crea una clave privada no se cifrará.

La documentación es en realidad más detallada que la anterior, la resumí aquí.


353
2018-04-13 01:48



No puedo hacer ningún comentario, así que pondré esto como una respuesta separada. Encontré algunos problemas con la respuesta aceptada de una línea:

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

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

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

Reemplaza 'localhost' con cualquier dominio que necesites. Tendrá que ejecutar los dos primeros comandos uno por uno, ya que openssl solicitará una frase de contraseña.

Para combinar los dos en un archivo .pem:

cat server.crt server.key > cert.pem

106
2017-08-13 09:44



El siguiente comando:

openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout example.key -out example.crt -subj "/CN=example.com" -days 3650

crea un certificado para el dominio example.com es decir

  • relativamente fuerte (a partir de 2018) y
  • valido para 3650 días (~ 10 años).

Crea los siguientes archivos:

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

Como toda la información se proporciona en la línea de comandos, no hay entrada interactiva molesta. Además, todos los pasos necesarios se ejecutan mediante esta única invocación de OpenSSL: desde la generación de claves privadas hasta el certificado autofirmado.

Dado que el certificado es autofirmado y debe ser aceptado por los usuarios manualmente, no tiene sentido utilizar una caducidad corta o una criptografía débil.

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

Nota al margen: Teóricamente podrías dejar de lado el -nodes parámetro (que significa "sin encriptación DES"), en cuyo caso example.key sería encriptado con una contraseña Sin embargo, esto casi nunca es útil para una instalación de servidor, ya que tendría que almacenar la contraseña en el servidor también, o tendría que ingresarla manualmente en cada reinicio.


105
2017-12-28 17:30



Yo recomendaría agregar -sha256 parámetro, 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 añadido

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

Más información en Blog de Google Security.

Actualización de mayo de 2018. Como se señaló en los comentarios, el uso de SHA-2 no agrega ningún tipo de seguridad al certificado autofirmado. Pero todavía recomiendo usarlo como un buen hábito de no usar funciones hash criptográficas desactualizadas / inseguras. La explicación completa está disponible en: https://security.stackexchange.com/questions/91913/why-is-it-fine-for-certificates-above-the-end-entity-certificate-to-be-sha1-base


63
2017-10-20 09:52



Los navegadores modernos ahora arrojan un error de seguridad para los certificados autofirmados bien formados si faltan una SAN (Nombre alternativo del sujeto). OpenSSL no proporciona una forma de línea de comandos para especificar esto, muchos de los tutoriales y marcadores de los desarrolladores están desactualizados de repente.

La forma más rápida de volver a ejecutar es un archivo conf breve y autónomo:

  1. Crea 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. Crea 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
    

Ejemplo de configuración de https://support.citrix.com/article/CTX135602


53
2018-05-09 02:37



Esta es la secuencia de comandos que uso en los cuadros 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. Las siguientes secciones están comentadas. Nombre el script (p. generate-ssl.sh) y darle permisos ejecutables. Los archivos se escribirán en el mismo directorio que el script.

Chrome 58 en adelante requiere que la SAN se configure 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 = webmaster@$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"

Este script también escribe un archivo de información para que pueda 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 de la siguiente manera:

<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 el nuevo certificado surta efecto.


11
2018-05-13 20:21