Saltar al contenido

Generación de un certificado autofirmado con openssl que funciona en Chrome 58

Este grupo de trabajo ha estado largas horas investigando soluciones a tus preguntas, te ofrecemos la solución de modo que deseamos que te sea de mucha apoyo.

Solución:

Solución 1:

Mi solución:

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

Estado: funciona para mí

Solucion 2:

En Windows, guarde este script en su carpeta SSL como makeCERT.bat. Creará estos archivos: example.cnf, example.crt, example.key

@echo off

REM IN YOUR SSL FOLDER, SAVE THIS FILE AS: makeCERT.bat
REM AT COMMAND LINE IN YOUR SSL FOLDER, RUN: makecert
REM IT WILL CREATE THESE FILES: example.cnf, example.crt, example.key
REM IMPORT THE .crt FILE INTO CHROME Trusted Root Certification Authorities
REM REMEMBER TO RESTART APACHE OR NGINX AFTER YOU CONFIGURE FOR THESE FILES

REM PLEASE UPDATE THE FOLLOWING VARIABLES FOR YOUR NEEDS.
SET HOSTNAME=example
SET DOT=com
SET COUNTRY=US
SET STATE=KS
SET CITY=Olathe
SET ORGANIZATION=IT
SET ORGANIZATION_UNIT=IT Department
SET [email protected]%HOSTNAME%.%DOT%

(
echo [req]
echo default_bits = 2048
echo prompt = no
echo default_md = sha256
echo x509_extensions = v3_req
echo distinguished_name = dn
echo:
echo [dn]
echo C = %COUNTRY%
echo ST = %STATE%
echo L = %CITY%
echo O = %ORGANIZATION%
echo OU = %ORGANIZATION_UNIT%
echo emailAddress = %EMAIL%
echo CN = %HOSTNAME%.%DOT%
echo:
echo [v3_req]
echo subjectAltName = @alt_names
echo:
echo [alt_names]
echo DNS.1 = *.%HOSTNAME%.%DOT%
echo DNS.2 = %HOSTNAME%.%DOT%
)>%HOSTNAME%.cnf

openssl req -new -x509 -newkey rsa:2048 -sha256 -nodes -keyout %HOSTNAME%.key -days 3560 -out %HOSTNAME%.crt -config %HOSTNAME%.cnf

Solución 3:

Aquí hay una solución que me funciona:

Crear clave y certificado de CA

# openssl genrsa -out server_rootCA.key 2048
# openssl req -x509 -new -nodes -key server_rootCA.key -sha256 -days 3650 -out server_rootCA.pem

Cree server_rootCA.csr.cnf

# server_rootCA.csr.cnf
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[dn]
C=DE
ST=Berlin
L=NeuKoelln
O=Weisestrasse
OU=local_RootCA
[email protected]
CN = server.berlin

Crear archivo de configuración v3.ext

# v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = server.berlin

Crear clave de servidor

# openssl req -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout server.key -config <( cat server_rootCA.csr.cnf )

Crear certificado de servidor

# openssl x509 -req -in server.csr -CA server_rootCA.pem -CAkey server_rootCA.key -CAcreateserial -out server.crt -days 3650 -sha256 -extfile v3.ext

Agregue certificado y clave al archivo de sitio Apache2, sección HTTPS (puerto 443)

SSLCertificateFile    /etc/apache2/ssl/server.crt
SSLCertificateKeyFile    /etc/apache2/ssl/server.key

Copie server_rootCA.pem del servidor a su máquina ..

# scp [email protected]:~/server_rootCA.pem .

.. y agréguelo al navegador Chromium

Chromium -> Setting -> (Advanced) Manage Certificates -> Import -> 'server_rootCA.pem'

¡ESTÁ TODO HECHO!

PD En lugar de crear un par de certificados de CA y servidor funcional (según las instrucciones anteriores), simplemente puede deshabilitar los encabezados HSTS en la configuración de su servidor HTTP. Esto evitará que Chromium aplique HTTPS y permitirá a los usuarios hacer clic en “Avanzado → continuar con your.url (inseguro)” sin tener que obtener e instalar su certificado CA personalizado (server_rootCA.pem). En otras palabras, tener que deshabilitar HSTS permitirá que su sitio se vea públicamente a través de HTTP y / o una conexión HTTPS insegura (¡cuidado!).

Para Apache2, agregue lo siguiente al archivo de sitio, sección HTTP (puerto 80)

Header unset Strict-Transport-Security
Header always set Strict-Transport-Security "max-age=0;includeSubDomains"

Probado en Debian / Apache2.4 + Debian / Chromium 59

https://ram.k0a1a.net/self-signed_https_cert_after_chrome_58


Solución 4:

Hay varias respuestas excelentes que brindan ejemplos de cómo hacer que esto funcione, pero ninguna que explique dónde salió mal en su intento. OpenSSL puede ser bastante poco intuitivo algunas veces, por lo que vale la pena analizarlo.

Primero, como acotación al margen, OpenSSL por defecto ignora cualquier valor de nombre distinguido que proporcione en el archivo config. Si quieres usarlos debes agregar prompt = no
a tu config. Además, el comando tal como está escrito solo genera un certificado
solicitud no un certificado en sí, por lo que el -days el comando no hace nada.

Si genera su solicitud de certificado usando este comando que dio e inspecciona el resultado, el nombre alternativo del sujeto está presente:

$ openssl req -new -key server.key -out server.csr -config config.cnf -sha256
$ openssl req -text -noout -in server.csr
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = US, ST = Massachusetts, L = Boston, O = MyCompany
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ...
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Subject Alternative Name:
                DNS:dev.mycompany.com
    Signature Algorithm: sha256WithRSAEncryption
         ...

Pero luego, si genera el certificado usando el comando en el enlace heroku e inspecciona el resultado, falta el nombre alternativo del sujeto:

$ openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt
$ openssl x509 -text -noout -in server.crt
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            89:fd:75:26:43:08:04:61
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, ST = Massachusetts, L = Boston, O = MyCompany
        Validity
            Not Before: Jan 21 04:27:21 2018 GMT
            Not After : Jan 21 04:27:21 2019 GMT
        Subject: C = US, ST = Massachusetts, L = Boston, O = MyCompany
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ...
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         ...

El motivo es que, de forma predeterminada, OpenSSL no copia extensiones de la solicitud al certificado. Normalmente, el certificado sería creado / firmado por una CA en base a una solicitud de un cliente, y algunas extensiones podrían otorgar al certificado más poder de lo que la CA pretendía si confiaran ciegamente en las extensiones definidas en la solicitud.

Hay formas de decirle a OpenSSL que copie las extensiones, pero en mi humilde opinión, es más trabajo que simplemente proporcionar las extensiones en un archivo de configuración cuando genera el certificado.

Si intentara usar su archivo de configuración existente, no funcionará porque la sección de nivel superior está marcada [req] por lo que esas configuraciones solo se aplican al comando req, no al comando x509. No es necesario tener un marcador de sección de nivel superior, por lo que puede eliminar esa primera línea y luego funcionará bien tanto para generar solicitudes como para certificados.

$ openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt -extfile config.cnf

Alternativamente, puede usar el -x509 argumento a la req comando para generar un certificado autofirmado en un solo comando, en lugar de crear primero una solicitud y luego un certificado. En este caso no es necesario quitar el
[req] línea de sección, ya que esa sección es leída y utilizada por el comando req.

$ openssl req -x509 -sha256 -days 365 -key server.key -out server.crt -config config.cnf

Para recapitular, aquí está el archivo de configuración modificado utilizado en los comandos anteriores:

default_bits        = 2048
distinguished_name  = dn
x509_extensions     = san
req_extensions      = san
extensions          = san
prompt              = no
[ dn ]
countryName         = US
stateOrProvinceName = Massachusetts
localityName        = Boston
organizationName    = MyCompany
[ san ]
subjectAltName      = DNS:dev.mycompany.com

Solución 5:

Script de bash con la configuración incorporada

Como un script de shell que debería funcionar en todas las plataformas con bash. Asume HOSTNAME env establecido para el shell o proporcione un nombre de host de su elección, por ejemplo self_signed_cert.sh test

set -e

if [ -z "$1" ]; then
  hostname="$HOSTNAME"
else
  hostname="$1"
fi
    
local_openssl_config="
[ req ]
prompt = no
distinguished_name = req_distinguished_name
x509_extensions = san_self_signed
[ req_distinguished_name ]
CN=$hostname
[ san_self_signed ]
subjectAltName = DNS:$hostname, DNS:localhost, IP:127.0.0.1, IP:::1
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = CA:true
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment, keyCertSign, cRLSign
extendedKeyUsage = serverAuth, clientAuth, timeStamping
"
    
openssl req 
  -newkey rsa:2048 -nodes 
  -keyout "$hostname.key.pem" 
  -x509 -sha256 -days 3650 
  -config <(echo "$local_openssl_config") 
  -out "$hostname.cert.pem"
openssl x509 -noout -text -in "$hostname.cert.pem"

Lo anterior más o menos inyecta la información mínima del archivo de configuración que necesita openssl.

Nota, incluido extra DNS:localhost como SAN para permitir las pruebas a través de localhost más fácilmente. Elimine ese bit extra del script si no lo desea.

Crédito

La respuesta de bcardarella es excelente (no se puede comentar / votar debido a un representante insuficiente). Sin embargo, la respuesta usa una ubicación de archivo de configuración de openssl existente que es específica de la plataforma ... por lo tanto:

Funciona para mi

Obviamente, uno simplemente necesitaría encontrar el archivo de configuración de openssl para su propia plataforma dada y sustituir la ubicación correcta.

Prueba

Para probar, importa test.cert.pem a las autoridades de Chrome en chrome://settings/certificates, y:

openssl s_server -key test.key.pem -cert test.cert.pem -accept 20443 -www &
openssl_pid=$!
google-chrome "https://localhost:20443"
google-chrome "https://127.0.0.1:20443"
google-chrome "https://[::1]:20443"

Y despues de probar

kill $openssl_pid

No se te olvide compartir este ensayo si te valió la pena.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *