crear un certificado SSL autofirmado de confianza para localhost (para usar con Express / Node)

130

Intentando seguir varias instrucciones sobre cómo crear un certificado autofirmado para usar con localhost. La mayoría de las instrucciones parecen ser para IIS, pero estoy tratando de usar Nodejs / Express. Ninguno de ellos funciona correctamente porque si bien el certificado se instala, no es confiable. Esto es lo que he intentado que falla:

¿Alguien puede ofrecer un flujo de trabajo que pueda hacer esto? Puedo instalar un certificado, pero no puedo confiar en él en Chrome (v32) o IE (v10).

EDITAR: se sugirió en los comentarios que el problema no es un certificado raíz confiable. Instalé el certificado a través de IE pero todavía no se confía en él.

JasonS
fuente
Ninguno de los certificados autofirmados puede ser confiable para los navegadores web. No están firmados por autoridades de firma de confianza.
1
eso no es cierto: puede instalar un certificado raíz para obtener su certificado autofirmado de confianza. Sin embargo, parece que no puedo hacer esto correctamente. Leí que puedes instalar la cadena de certificados en IE (no en Chrome), así que lo intenté pero todavía no se reconoce. No sé si es porque localhost es especial o si el certificado autofirmado no es correcto.
JasonS
3
Nunca obtuve un certificado autofirmado que funcionara con navegadores como Chrome. Aquí está mi solución: creé una entrada DNS para local.MYDOMAIN.com apuntando a 127.0.0.1 (localhost) y luego simplemente uso mi certificado de producción. Esto tiene el beneficio adicional de asegurarse de que no haya problemas con su cadena de
certificados de

Respuestas:

86

Las respuestas anteriores fueron parciales. He pasado tanto tiempo haciendo que esto funcione, es una locura. Nota para mi futuro yo, esto es lo que debes hacer:

Estoy trabajando en Windows 10, con Chrome 65. Firefox se está comportando bien, solo confirme localhost como una excepción de seguridad y funcionará. Chrome no:

Paso 1. en tu backend, crea una carpeta llamada security. Trabajaremos en su interior.

Paso 2. cree un archivo de configuración de solicitud req.cnfcon el siguiente contenido (el crédito va a: @Anshul )

req.cnf:

[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = Country initials like US, RO, GE
ST = State
L = Location
O = Organization Name
OU = Organizational Unit 
CN = www.localhost.com
[v3_req]
keyUsage = critical, digitalSignature, keyAgreement
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.localhost.com
DNS.2 = localhost.com
DNS.3 = localhost

Una explicación de estos campos está aquí .

Paso 3. navega a la carpeta de seguridad en la terminal y escribe el siguiente comando:

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

Paso 4. luego fuera de la securitycarpeta, en su aplicación express haga algo como esto: (el crédito va a @Diego Mello)

backend 
 /security
 /server.js

server.js:

const express = require('express')
const app = express()
const https = require('https')
const fs = require('fs')
const port = 3000

app.get('/', (req, res) => {
    res.send("IT'S WORKING!")
})

const httpsOptions = {
    key: fs.readFileSync('./security/cert.key'),
    cert: fs.readFileSync('./security/cert.pem')
}
const server = https.createServer(httpsOptions, app)
    .listen(port, () => {
        console.log('server running at ' + port)
    })

Paso 5. Inicie el servidor, node server.jsy vaya a https: // localhost: 3000 .

En este punto tenemos la configuración del servidor. Pero el navegador debe mostrar un mensaje de advertencia.

Necesitamos registrar nuestro certificado autofirmado, como una Autoridad de Certificación de confianza de CA, en la tienda de certificados de Chrome / Windows. (Chrome también guarda esto en Windows)

Paso 6. abre Dev Tools en Chrome, ve al Panel de seguridad, luego haz clic en Ver certificado. ingrese la descripción de la imagen aquí

Paso 7. vaya al panel Detalles, haga clic en Copiar archivo, luego, cuando aparezca el Asistente de exportación de certificados, haga clic en Siguiente como se muestra a continuación:

ir a detalles - copiar archivo - siguiente en el asistente de exportación

Paso 8. Deje la codificación DER, haga clic en Siguiente, elija Browse, colóquelo en una carpeta de fácil acceso como Escritorio y asigne un nombre al certificado localhost.cer, then click Save and then Finish.. Debería poder ver su certificado en el escritorio.

Paso 9. Ábralo chrome://settings/insertándolo en el cuadro de URL. Abajo, haga clic en Advanced / Advanced Options, luego desplácese hacia abajo para encontrar Manage Certificates.

elige administrar certificados

Paso 10. Vaya al panel Autoridades de certificación raíz de confianza y haga clic en importar.

Vaya al panel Autoridades de certificación raíz de confianza y haga clic en importar

Importaremos el localhost.cercertificado que acabamos de exportar en el paso 8.

Paso 11. Haz clic en Examinar, encuentra los localhost.cervalores predeterminados, haz clic en Siguiente varias veces. Hasta que aparezca esta advertencia, haz clic en Sí.

confirmar excepción de seguridad

Paso 12. cierra todo y reinicia Chrome. Entonces, cuando https://localhost:3000vayas deberías ver: tengo que amar el verde

AIon
fuente
Hola, cuando termino todos los pasos que abro https://localhost:3000y Chrome se atasca al cargar. ¿Alguien puede decir cuál podría ser la razón?
co.zohar
@ co.zohar algún mensaje en la consola? Presione crl+shift+io F12para abrir la consola.
AIon
1
Si está haciendo esto para una dirección en una red, descubrí que configurar el certificado DNS a un nombre de host como: DNS.1 = server.local Luego, en la máquina de conexión, actualice el archivo HOSTS para apuntar la dirección IP del servidor al nombre de host, por ejemplo: 192.168.0.50 server.localEsto permita que el certificado y la dirección coincidan y validen el certificado.
roskelld
@AIon la consola no muestra nada. La página solo muestra: "Esperando localhost ...". ¿Configuraste algo en el archivo de hosts?
co.zohar
1
Encontré una semi-respuesta a mi propia pregunta: si cambia CN y DNS.1 a algo como "local.com", por ejemplo, y en cada computadora que necesita acceso al servidor, cambie el archivo etc / hosts para señalar local .com a la ip del servidor, esto funciona.
TKoL
111

El camino más corto Probado en MacOS, pero puede funcionar de manera similar en otros sistemas operativos.

Generar pem

> openssl req -x509 -newkey rsa:2048 -keyout keytmp.pem -out cert.pem -days 365

> openssl rsa -in keytmp.pem -out key.pem

Su servidor express

const express = require('express')
const app = express()
const https = require('https')
const fs = require('fs')
const port = 3000

app.get('/', (req, res) => {
  res.send('WORKING!')
})

const httpsOptions = {
  key: fs.readFileSync('./key.pem'),
  cert: fs.readFileSync('./cert.pem')
}
const server = https.createServer(httpsOptions, app).listen(port, () => {
  console.log('server running at ' + port)
})
  • Abra https://localhost:3000en Google Chrome y verá que no es seguro. ¡Todavía!
  • En Herramientas para desarrolladores> Seguridad> Ver certificado: arrastre la imagen a su escritorio y haga doble clic en ella.
  • Haga clic en 'Agregar'
  • Encuéntrelo en Keychain Access y haga doble clic en él.
  • Expanda 'Confiar' y cambie 'Al usar este certificado' a 'Confiar siempre'.
  • Se le puede solicitar que se autentique.
  • Reinicia tu servidor.
  • Actualiza tu navegador.
  • ¡Disfrutar! :)
Diego Mello
fuente
1
Aquí hay otro enlace si desea hacerlo en Mac: certsimple.com/blog/localhost-ssl-fix .
John
¡Hermoso! Esto funcionó! Me gustaría agregar: Instale OpenSSL desde aquí: indy.fulgan.com/SSL/?C=M;O=A . Obtenga el archivo .cnf desde aquí: y luego configúrelo desde aquí: gist.githubusercontent.com/pandurang90/dbe6a67339747ef5bacf/raw/… y configure openSSL desde aquí: stackoverflow.com/questions/7360602/…
Jose A
2
Me gustaría agregar que para Chrome 58+, recibirá un error "Falta el nombre alternativo del sujeto". stackoverflow.com/a/42917227/1057052 . Consulte las respuestas a continuación para obtener más ayuda: stackoverflow.com/a/43666288/1057052 , stackoverflow.com/a/44398368/1057052
Jose A
14
Drag image to your desktop and double click it-> No puedo arrastrar nada a mi escritorio, no es arrastrable. ¿De qué imageestás hablando exactamente?
AIon
77
Para superar "Falta el nombre alternativo del sujeto" en Chrome, puede hacerlo en openssl req -newkey rsa:2048 -x509 -nodes -keyout keytmp.pem -new -out cert.pem -subj /CN=localhost -reqexts SAN -extensions SAN -config <(cat /System/Library/OpenSSL/openssl.cnf <(printf '[SAN]\nsubjectAltName=DNS:localhost')) -sha256 -days 3650lugar de la primera línea que sugirió. Y también este hará menos preguntas en el proceso ...
Michael Litvin
78

Puedes probar openSSL para generar certificados. Mira esto .

Necesitará un archivo .key y .crt para agregar HTTPS al servidor JS express del nodo. Una vez que genere esto, use este código para agregar HTTPS al servidor.

var https = require('https');
var fs = require('fs');
var express = require('express');

var options = {
    key: fs.readFileSync('/etc/apache2/ssl/server.key'),
    cert: fs.readFileSync('/etc/apache2/ssl/server.crt'),
    requestCert: false,
    rejectUnauthorized: false
};


var app = express();

var server = https.createServer(options, app).listen(3000, function(){
    console.log("server started at port 3000");
});

Esto funciona bien en mi máquina local, así como en el servidor donde lo implementé. El que tengo en el servidor fue comprado en goDaddy pero localhost tenía un certificado autofirmado.

Sin embargo, cada navegador arrojó un error diciendo que la conexión no es confiable, ¿desea continuar? Después de hacer clic en continuar, funcionó bien.

Si alguien ha pasado por alto este error con un certificado autofirmado, por favor, ilumine.

Mars Robertson
fuente
9
Su certificado aún no es confiable, por lo que tiene el mismo problema que estoy describiendo. Necesito que sea confiable para probar / depurar un servicio web correctamente.
JasonS
1
¿Desea que se confíe en este certificado solo en su máquina local y no en la red?
1
el enlace en la parte superior de la respuesta recomienda el cifrado 3DES de 1024 bits, que está muy desactualizado. Mejor usar openssl genrsa -out key.pem 2048para una mejor clave.
impulsado por vapor el
3
Su certificado aún no es confiable.
Diego Mello
2
el código expreso anterior funciona, utilizando github.com/FiloSottile/mkcert (en lugar de openSSL) para crear una CA local / certificado de confianza. Barras verdes hasta el final.
som
11

Cómo generar un certificado SSL para localhost: enlace

openssl genrsa -des3 -out server.key 1024

debe ingresar una contraseña aquí que debe volver a escribir en los siguientes pasos

openssl req -new -key server.key -out server.csr

cuando se le pregunte "Nombre común" escriba: localhost

openssl x509 -req -days 1024 -in server.csr -signkey server.key -out server.crt
fuma
fuente
1
Esta es la solución que he buscado en Internet durante las últimas 2 horas. Para cualquier persona en ubuntu, mueva cp server.crt /usr/local/share/ca-certificates/.y ejecute. sudo update-ca-certificatesLuego, las solicitudes localhost https funcionan en NodeJS 8+. La identificación también aumentará1024 to 2048
Salyangoz
6

Esto es lo que me funciona

en ventanas

1) Agregue esto a su archivo% WINDIR% \ System32 \ drivers \ etc \ hosts: 127.0.0.1 localdev.YOURSITE.net (porque el navegador tiene problemas con 'localhost' (para secuencias de comandos de origen cruzado)

Windows Vista y Windows 7 Vista y Windows 7 utilizan el Control de cuentas de usuario (UAC), por lo que el Bloc de notas debe ejecutarse como Administrador.

  1. Haga clic en Inicio -> Todos los programas -> Accesorios

  2. Haga clic derecho en el Bloc de notas y seleccione Ejecutar como administrador

  3. Haga clic en Continuar en la ventana UAC "Windows necesita su permiso".

  4. Cuando se abre el Bloc de notas, haga clic en Archivo -> Abrir

  5. En el campo de nombre de archivo, escriba C: \ Windows \ System32 \ Drivers \ etc \ hosts

  6. Haga clic en Abrir

  7. Agregue esto a su archivo% WINDIR% \ System32 \ drivers \ etc \ hosts: 127.0.0.1 localdev.YOURSITE.net

  8. Salvar

  9. Cerrar y reiniciar navegadores

En Mac o Linux:

  1. Abra / etc / hosts con supermiso
  2. Añadir 127.0.0.1 localdev.YOURSITE.net
  3. Guardarlo

Al desarrollar, utiliza localdev.YOURSITE.net en lugar de localhost, por lo que si está utilizando configuraciones de ejecución / depuración en su ide, asegúrese de actualizarlo.

Use ".YOURSITE.net" como dominio de cocina (con un punto al principio) al crear el cookiem, entonces debería funcionar con todos los subdominios.

2) crea el certificado usando ese localdev.url

SUGERENCIA: si tiene problemas para generar certificados en Windows, utilice una máquina VirtualBox o Vmware.

3) importe el certificado como se describe en http://www.charlesproxy.com/documentation/using-charles/ssl-certificates/

TroyWorks
fuente
Hola Troy, gracias por compartir esto. Alguien más tendrá que comentar si esto funciona o no. Mi solución: terminé agregando dev.phantomjscloud.com a mi archivo de hosts y luego usando mi certificado de producción. Sin embargo, eso solo es útil si desea que sus claves de producción estén disponibles en su caja de desarrollo, por lo que creo que su solución aún podría ser válida, si alguien más puede verificarlo
JasonS
Funciona para mí y para mi equipo, en una combinación de formas, asegurar el servidor local a local para asegurar el servidor local al de producción.
TroyWorks
Para Windows, la consola git bash funciona muy bien usando comandos openssl desde aquí . Solo tiene que instalar el certificado raíz y puede crear varios certificados específicos del sitio firmados por él si lo desea.
Jason Goemaat
6

Mkcert de @FiloSottile hace este proceso infinitamente más simple:

  1. Instale mkcert , hay instrucciones para macOS / Windows / Linux
  2. mkcert -install para crear una CA local
  3. mkcert localhost 127.0.0.1 ::1 para crear un certificado de confianza para localhost en el directorio actual
  4. Está utilizando el nodo (que no utiliza el almacén raíz del sistema), por lo que debe especificar la CA explícitamente en una variable de entorno, por ejemplo:export NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem"
  5. Finalmente, ejecute su servidor express utilizando la configuración descrita en varias otras respuestas (por ejemplo, a continuación)
  6. auge. localhost está nadando en verde.

Configuración básica del nodo:

const https = require('https');
const fs = require('fs');
const express = require('express');

const app = express();    
const server = https.createServer({
    key: fs.readFileSync('/XXX/localhost+2-key.pem'), // where's me key?
    cert: fs.readFileSync('/XXX/localhost+2.pem'), // where's me cert?
    requestCert: false,
    rejectUnauthorized: false,
}, app).listen(10443); // get creative
som
fuente
Funciona mucho! Con este enfoque, no necesitamos registrar nuestro certificado autofirmado, como Autoridad de Certificación de confianza de CA, en la tienda de certificados de Chrome / Windows. Como se menciona en otras respuestas.
zaheer
4

Si utiliza OSX / Chrome, puede agregar el certificado SSL autofirmado al llavero de su sistema como se explica aquí: http://www.robpeck.com/2010/10/google-chrome-mac-os-x-and -self-firmado-ssl-certificados

Es un proceso manual, pero finalmente lo hice funcionar. Solo asegúrese de que el Nombre común (CN) esté configurado en "localhost" (sin el puerto) y después de agregar el certificado, asegúrese de que todas las opciones de Confianza en el certificado estén configuradas en "Confiar siempre". También asegúrese de agregarlo al llavero "Sistema" y no al llavero "inicio de sesión".

Vijay Rudraraju
fuente
Menciona IE, lo que significa que está usando Windows.
2 bits
3

Si está utilizando el nodo, ¿por qué no generarlos con el nodo? Este módulo parece ser bastante completo:

Tenga en cuenta que no generaría sobre la marcha. Genere con algún tipo de script de compilación para que tenga un certificado y una clave coherentes. De lo contrario, deberá autorizar el certificado autofirmado recientemente generado cada vez.

BT
fuente
3

Algunas de las respuestas publicadas tienen piezas que me fueron muy útiles para superar este problema también. Sin embargo, también estaba interesado en el número mínimo de pasos e, idealmente, evitar OpenSSL (en Windows 10).

Entonces, una parte crítica de las respuestas (crédito: @ TroyWorks ) es que necesita editar su archivo HOSTS para crear un servidor ficticio y asignarlo a 127.0.0.1. Esto supone que vas a estar haciendo desarrollo local.

En mi caso, estaba usando el certificado SS para asegurar un websocket en NodeJS, y ese socket se estaba conectando mediante programación (en lugar de a través del navegador). Entonces, para mí, fue crítico que el certificado fuera aceptado sin advertencias o errores, y la pieza crítica allí era obtener el certificado creado con un CN adecuado (y, por supuesto, aceptar el certificado en Autoridades de confianza, como se describe en otras partes de las respuestas) . El uso de IIS para crear un certificado autofirmado no creará el CN ​​adecuado, por lo que descubrí el siguiente comando simple usando Powershell:

New-SelfSignedCertificate -DnsName "gandalf.dummy.dev" -FriendlyName "gandalf" -CertStoreLocation "cert:\LocalMachine\My"

Esto debe ejecutarse en la consola PS Admin, pero simplemente funciona y coloca el certificado en la sección "Personal" del almacén de certificados LocalMachine. Puede verificar que se creó ejecutando:

ls cert:\LocalMachine\My 

Para confiar en él, simplemente copie esto y péguelo en "Autoridades de certificación raíz de confianza" usando el Administrador de certificados (asegurándose de que esté mirando los certificados de máquina local, ¡no el usuario actual!).

Si se une a este certificado en IIS, debería poder acceder a https://gandalf.dummy.dev/ y obtener una conexión segura sin advertencias.

La pieza final, usando esto en NodeJS, se describe arriba y en otras respuestas SO, por lo que solo agregaré eso en Windows, es más fácil trabajar con un archivo pfx que combina el certificado y la clave privada. Puede exportar un pfx fácilmente desde el Administrador de certificados, pero afecta la forma en que lo usa en NodeJS. Al crear instancias de un servidor utilizando el módulo 'https', las opciones que usaría (en lugar de 'clave' y 'cert') serían 'pfx' y 'frase de contraseña', como en:

var https = require('https');
var options = { 
    pfx: fs.readFileSync('mypfxfile'), 
    passphrase: 'foo' 
};
var server = https.createServer(options);
tomo
fuente
2

en Windows hice que el certificado de desarrollo de iis fuera de confianza usando MMC (inicio> ejecutar> mmc), luego agregué el complemento de certificado, seleccioné "equipo local" y acepté los valores predeterminados. Una vez que se agrega ese complemento de certificado, expanda el árbol de certificados de la computadora local para buscar en Personal, seleccione el certificado de host local, haga clic con el botón derecho> todas las tareas> exportar. acepte todos los valores predeterminados en el asistente de exportación.

Una vez que se guarda ese archivo, expanda los certificados de confianza y comience a importar el certificado que acaba de exportar. https://localhostahora se confía en Chrome sin advertencias de seguridad.

Utilicé esta resolución de guía # 2 del blog de MSDN, el operador también compartió un enlace en su pregunta sobre que también debería usar MMC, pero esto funcionó para mí. resolución # 2

Mushcraft
fuente
2

Ir: chrome://flags/

Activar: permite certificados no válidos para recursos cargados desde localhost.

No tiene la seguridad verde, pero siempre tiene permiso para https: // localhost en Chrome.

Alphapage
fuente
2

Hay más aspectos en esto.

Puede lograr TLS (algunos siguen diciendo SSL) con un certificado, autofirmado o no.

Para tener una barra verde para un certificado autofirmado, también debe convertirse en la Autoridad de certificación (CA). Este aspecto falta en la mayoría de los recursos que encontré en mi viaje para lograr la barra verde en mi configuración de desarrollo local. Convertirse en CA es tan fácil como crear un certificado.

Este recurso cubre la creación tanto del certificado de CA como del certificado del servidor, y mi configuración mostró una barra verde en Chrome localhost, Firefox y Edge: https://ram.k0a1a.net/self-signed_https_cert_after_chrome_58

Tenga en cuenta: en Chrome debe agregar el certificado de CA a sus autoridades de confianza.

Jos
fuente
0

Si necesita ir un paso más allá de los pasos detallados de @ alon y también crear un ca autofirmado:

https.createServer({
  key: fs.readFileSync(NODE_SSL_KEY),
  cert: fs.readFileSync(NODE_SSL_CERT),
  ca: fs.readFileSync(NODE_SSL_CA),
}, app).listen(PORT, () => {});

package.json

"setup:https": "openssl genrsa -out src/server/ssl/localhost.key 2048
&& openssl req -new -x509 -key src/server/ssl/localhost.key -out src/server/ssl/localhost.crt -config src/server/ssl/localhost.cnf
&& openssl req -new -out src/server/ssl/localhost.csr -config src/server/ssl/localhost.cnf
&& openssl x509 -req -in src/server/ssl/localhost.csr -CA src/server/ssl/localhost.crt -CAkey src/server/ssl/localhost.key -CAcreateserial -out src/server/ssl/ca.crt",

Usando el localhost.cnf como se describe:

[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = UK
ST = State
L = Location
O = Organization Name
OU = Organizational Unit 
CN = www.localhost.com
[v3_req]
keyUsage = critical, digitalSignature, keyAgreement
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.localhost.com
DNS.2 = localhost.com
DNS.3 = localhost
momiabot
fuente