KeyTool genera cadena de certificados y su aplicación en java y c#

        La mayor parte del contenido de este artículo se aprende de Internet, por lo que le daré la vuelta a Internet después de resumir. Si encuentra un error, o tiene una mejor manera, puede comentar o enviarme un mensaje.

        La razón para explorar la cadena de certificados es que los certificados autofirmados se utilizan en el desarrollo de la cuadrícula mínima . Simple Grid es un marco de desarrollo para pequeñas y microempresas que integra el dispositivo y la nube. Si solicita un certificado de la organización cada vez que lo implementa, primero será muy problemático y el segundo es el costo. Los servicios de Simple Grid son de uso gratuito, pero se cobrará el certificado. En resumen, después de tantear la cadena de certificados, se genera el certificado raíz y luego se firma el certificado de segundo nivel. El certificado de segundo nivel se divide en el certificado del servidor y el certificado de firma de la aplicación. El certificado del servidor y el certificado de firma de la aplicación son los certificados de tercer nivel.

        Por cierto, un pequeño anuncio, el código comercial de Zhijian Grid se ha abierto gradualmente, bienvenido a visitar Code Cloud o CSDN para verlo, y también está disponible en GitHub.

Tabla de contenido

1. Conceptos básicos

1.1. SSL

1.2 ¿Qué es un certificado?

1.3 Tipos de certificados

1.4 Generación de certificados

1.5 Conceptos básicos

1.5.1. X.509

1.5.2 Formato de codificación de certificados (DER&PEM)

1.5.3 Extensiones relacionadas con certificados

1.6 Ver certificado

1.6.1. ventanas

1.6.2. Androide

2. Generar un certificado raíz

2.1 Generar almacén de claves de certificado raíz

2.2 Exportar el certificado raíz desde el almacén de claves del certificado raíz

3. Generar un certificado secundario

3.1 Generar un almacén de claves de certificado secundario

3.2 Generar una solicitud de certificado desde el almacén de claves de certificado secundario

3.4 Importar el certificado secundario al almacén de claves

4. Usar el certificado secundario para emitir certificados de usuario

4.1 Generar almacén de claves de certificado de usuario

4.2 Generación de solicitudes de certificados de usuario

4.3 Emisión de certificados de usuario con certificados secundarios

4.4 Importar certificados de usuario al almacén de claves

4.5 Ver cadena de certificados de usuario

4.6 Convertir JKS a BKS

5. Uso

5.1 Uso de certificados autofirmados en Java

5.1.1 Uso de certificados autofirmados en Netty

5.1.2 Uso de certificados autofirmados en OkHttp

5.2 Uso de certificados autofirmados en C#

5.3 Uso de certificados autofirmados en Android

5.4 Uso de certificados autofirmados en IE

5.4.1. ventanas

6. Resumen


1.  Conceptos básicos

1.1. SSL

        Los certificados se utilizan generalmente en el protocolo de transporte SSL (Secure Sockets Layer) para implementar el intercambio de claves entre el lado del terminal y el lado del servidor. Debería llamarse "TLS" ahora, pero debido a la costumbre, a menudo se llama "SSL". El uso más común de SSL es en sitios web, donde se utiliza para implementar una transmisión HTTP segura.

        La transmisión del protocolo HTTP no cifra el contenido, por lo que cuando se transmite el contenido, otros pueden monitorearlo. En escenarios con altos requisitos de seguridad, la transmisión debe estar encriptada, por ejemplo, el escenario de transmisión de contraseñas durante el inicio de sesión.

        HTTPS es el protocolo HTTP con encriptación, y la transmisión encriptada de HTTPS se implementa en base a SSL, de modo que incluso si un nodo en la transmisión de la red es monitoreado por otros, los datos no se filtrarán. SSL implementa el cifrado y el descifrado en la capa inferior de HTTP, y el cifrado y el descifrado son transparentes para los usuarios y desarrolladores. En otras palabras, antes del cifrado, cómo se implementa su servidor, después del cifrado, no es necesario realizar ningún cambio.

        Otro término es OpenSSL. En pocas palabras, SSL es una especificación y OpenSSL es una implementación de SSL, que proporciona un montón de herramientas poderosas, tan poderosas que no usamos el 90%. Teóricamente hablando, es difícil descifrar SSL en el nivel técnico actual, pero la implementación de SSL puede tener lagunas, como el famoso "Heartbleed".

1.2 ¿  Qué es un certificado?

        Los certificados se utilizan en SSL, entonces, ¿qué es un certificado?

        Un certificado puede entenderse como un documento que contiene información como información del emisor, información del propietario, clave pública, firma generada por la clave privada del emisor y, por supuesto, otra información. Verificar si el certificado de usuario es creíble es en realidad verificar si el certificado es emitido por una organización legal. Al verificar, busque el certificado de la organización correspondiente a través de la información estructural en el certificado y use la clave pública en el certificado de la organización para verificar si la firma en el certificado de usuario es correcta.

        A partir de los métodos de verificación anteriores, podemos ver que el certificado de su emisor verifica si el certificado es creíble, y el certificado de la organización de nivel superior verifica si el certificado de la organización es creíble, formando así una cadena de certificados El certificado de la organización de nivel superior a menudo se denomina certificado raíz.

        En el escenario del sitio web, el sitio web genera un almacén de claves, registra la clave pública del sitio web, la clave privada y alguna otra información, y luego solicita un certificado de la organización. El certificado generado incluye información como la clave pública y también incluye una cadena de certificados, que se utiliza para emitir a los usuarios del sitio web. Cuando un usuario visita un sitio web, primero descarga el certificado del sitio web, verifica la cadena de certificados y luego usa la clave pública para intercambiar claves con el sitio web.

1.3  Tipos de certificados

        Uno es un certificado autofirmado y el otro es un certificado emitido por una agencia.

        Un certificado autofirmado significa que el emisor es él mismo y utiliza su propia clave privada para firmar la información del certificado. Un certificado raíz es un certificado autofirmado. El cliente generalmente preestablece los certificados raíz de organizaciones conocidas y confía en los certificados emitidos por estos certificados raíz.

        Emitir certificados es emitir certificados a través de estas organizaciones, que pueden ser organizaciones de nivel raíz u organizaciones secundarias, y utilizar la clave privada de la organización para firmar la información del certificado. Para proteger el certificado raíz, normalmente la organización permitirá que las organizaciones secundarias y terciarias emitan certificados.

1.4  Generación de certificados

        El certificado y el almacén de claves correspondiente al certificado se pueden generar a través de la herramienta de claves proporcionada por openssl o jdk. Este artículo utiliza keytool como ejemplo. Después de comprender el proceso de generación de certificados, es fácil corresponder con el método de generación de openssl.

1.5  Conceptos básicos

        Simplemente busque certificados TLS y habrá muchas palabras clave: X.509, p12, pfx, pkcs, pem, csr, cer, crt, jks, crl, etc., tan complicadas que las personas pueden pasar rápidamente de comenzar a darse por vencidas. Entonces, clasifiquemos estas palabras clave primero.

1.5.1. X.509

        X.509 es un estándar de certificado digital ampliamente utilizado. En pocas palabras, define qué campos están contenidos en un certificado digital y cómo almacenarlos. Puede consultar RFC5280. PKCS7 y PKCS12 son dos paquetes involucrados en la especificación X509, que incluyen diferentes contenidos. PKCS7 se usa para la firma o el cifrado, y no contiene contenido de firma o cifrado; PKCS12 contiene clave privada, clave pública, protección con contraseña y es relativamente seguro.

        Los parámetros definidos en el protocolo X509 están todos codificados en DER (Reglas de codificación distinguidas, X.690). La codificación DER se puede entender como una codificación de formato TLV (Valor de longitud de etiqueta), tomando como ejemplo el contenido de un certificado real:

Certificado:

    Datos:

        Versión: 3 (0x2)          //Representado como certificado de versión X509 v3

        Número de serie: 1 (0x1)    //Número de serie, al emitir, es necesario asegurarse de que cada certificado del mismo emisor sea un Número de serie único

    Algoritmo de firma: sha256WithRSAEncryption //Algoritmo de firma, primero calcule el resumen SHA256 y luego use la clave privada del emisor para el cifrado RSA

        Emisor: C=CN,ST=JS, L=NJ, O=Dreamer, OU=Dreamer, CN=Dreamer // DN del emisor (Nombre distinguido), consulte las instrucciones de seguimiento

        Validez //Período de validez del certificado

            No antes: 29 de julio 14:02:13 2018 GMT

            No después: 26 de julio 14:02:13 2028 GMT

        Asunto: C=CN, ST=JS, O=Dreamer, OU=JM, CN=*.dreamer.com //Propietario del certificado DN (Nombre distinguido)

        Información de clave pública del sujeto:  //Información de clave pública del certificado

            Algoritmo de clave pública: rsaEncryption

                Clave pública: (1024 bits)

                Módulo:

                    00:c5:b8:68:a2:9c:bd:11:0c:83:34:a2:97:a5:8e:

                    72:75:2a:bc:f4:75:fc:d0:a3:47:7d:e4:6b:4f:ed:

                    dd:79:7c:0f:ce:6e:e7:d2:7d:10:cd:e8:07:56:34:

                    58:e3:2b:2e:c9:e3:7f:ae:27:2d:f7:a3:17:6f:dd:

                    65:d7:f8:4f:d0:be:9c:3b:9b:ea:ed:86:d2:19:67:

                    81:60:53:64:c9:d1:be:17:7d:5d:7f:cc:58:1d:b6:

                    e1:51:0d:ba:32:ac:4d:73:a4:fc:8f:6a:79:f9:44:

                    25:03:b6:1c:3e:0f:e9:b8:36:b1:07:07:59:54:40:

                    d7:2c:52:ab:68:fe:ed:e2:6f

                Exponente: 65537 (0x10001)

        Extensiones X509v3:  //información de la extensión de la versión v3

            Restricciones básicas de X509v3:  

                CA: FALSE   // Indica si el propietario del certificado es una organización de CA que puede emitir certificados. Si es True, también puede agregar una pathLengthConstraint para mostrar la longitud de la cadena de emisión.

            Comentario de Netscape:

                Certificado generado por OpenSSL

            Identificador de clave de sujeto X509v3: // ID de clave de propietario del certificado, esta extensión debe agregarse cuando CA: VERDADERO

                67:30:EE:FB:39:A4:92:56:9C:1A:E8:94:10:A4:3B:EA:EC:2E:04:9E

            Identificador de clave de autoridad X509v3: //El ID de clave correspondiente al emisor del certificado, utilizado para encontrar la clave pública del emisor (especialmente cuando hay varias claves)

                DirName:/C=CN/ST=JS/L=NJ/O=Soñador/OU=Soñador/CN=Soñador

                serie:A0:09:E3:A9:D2:C1:86:7C

            X509v3 Nombre alternativo del sujeto:  //El alias del propietario del certificado, utilizado para la emisión de certificados multidominio

                DNS:*.ejemplo.com, DNS:*.jm.com

    Algoritmo de firma: sha256WithRSAEncryption //Información de firma del certificado emitido por la autoridad emisora

         91:db:9b:0c:9b:6e:68:24:d3:2f:3a:67:b5:c0:6c:f0:c8:4c:

         f8:87:86:93:eb:fc:dc:ef:dc:7b:2e:2c:0e:7b:52:23:4d:de:

         d9:69:a8:ee:ae:aa:14:04:ca:1a:03:87:fe:11:60:fe:16:8f:

         87:9d:9e:d0:3a:be:33:03:f6:25:8a:10:37:f8:90:9d:67:5c:

         36:a6:1e:3c:59:d9:8f:eb:22:0e:f7:3c:7d:47:10:9b:0b:03:

         f0:8c:70:b0:3c:40:c6:5d:cc:6b:ba:40:ce:89:04:c7:3c:be:

         af:bd:1d:94:6b:83:39:29:74:de:12:fc:63:0d:0f:39:31:3b:

         48:

Además de las instrucciones en los comentarios, se deben agregar los siguientes puntos:

  • Tanto el Asunto como el Emisor están en formato DN, y los formatos comunes son: C=país, ST=provincia, L=distrito, O=organización, OU=unidad organizativa, CN=nombre común;
  • El DN es la clave para la búsqueda de la cadena de certificados. Durante la verificación, el certificado de la organización se comparará de acuerdo con el DN del Emisor. El método de coincidencia específico consiste en comparar el número de DN y el valor de cada parámetro de DN;
  • El nombre común de CN en DN es generalmente un nombre de dominio.Si necesita admitir nombres de subdominio, como server.com y bcd.server.com, puede usar la forma de nombre de dominio genérico *.server.com;
  • El campo de extensión Nombre alternativo del sujeto se puede utilizar para certificados de varios dominios.

1.5.2  Formato de codificación de certificados (DER&PEM)

        Según la declaración general en Internet, X.509 tiene dos formatos de almacenamiento: DER y PEM (Privacy Enhanced Mail). De hecho, esta declaración es algo inapropiada. De hecho, estos dos formatos de codificación no están al mismo nivel. Como se mencionó anteriormente, DER es un protocolo de codificación binaria en formato TLV.X.509 establece que la codificación de cada campo del certificado se puede codificar en formato DER. Sin embargo, PEM no comprende los parámetros internos de X. 509. En cambio, después de codificar X.509 con DER, realiza la codificación BASE64 en los datos binarios y luego agrega el encabezado y la cola del archivo, como se muestra a continuación:

-----BEGIN CERTIFICATE-----
MIICMTCCAZoCCQCgCeOp0sGGfDANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJD
TjELMAkGA1UECAwCSlMxCzAJBgNVBAcMAk5KMRAwDgYDVQQKDAdEcmVhbWVyMRAw
DgYDVQQLDAdEcmVhbWVyMRAwDgYDVQQDDAdEcmVhbWVyMB4XDTE4MDcyODE1NTEx
NFoXDTI4MDcyNTE1NTExNFowXTELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkpTMQsw
CQYDVQQHDAJOSjEQMA4GA1UECgwHRHJlYW1lcjEQMA4GA1UECwwHRHJlYW1lcjEQ
MA4GA1UEAwwHRHJlYW1lcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwjDr
aM8SubYIN/dqmJLCHYWBet7yQ80H3VPcbeYPja2Fq1VPb0vKMXzfd8BdaJ3roown
ZCJlfxCFPqN/z8/a0BS+ukmknOcYeYoN+vpVg9Oq3fH0iy+TRg+ydOVwmyAXJk0D
GS7WFjHv6DYRlH/xgKXuHGXwytNpQHZdDzq6bV0CAwEAATANBgkqhkiG9w0BAQsF
AAOBgQCaoAdYiWpGKcvc89ZPwL/Zd0KgSLnAln/38a69N5LqtDgWD9a6PDjHHmTF
/cN/p8hJ3LdEXfPGtFj06+KaG6OVOAo5RSqOHc5DcMs1nAImqIAuLt2rOCmsY+li
T9tweI2raih6OMTKAeIW5m46T28oPlNgeEMy2Uj2CevS6tCaLQ==
-----END CERTIFICATE-----

        El método para distinguir entre DER y PEM es muy simple. Abra el que tiene caracteres ilegibles en formato DER y abra el formato similar al anterior en formato PEM. En términos generales, la extensión del archivo que almacena DER es ".cer", que son datos binarios, mientras que la extensión del archivo que almacena PEM es ".crt", que es un archivo de texto ASCII.

        Los archivos DER/PEM se pueden ver con el siguiente comando:

openssl x509 -in certificate.der -inform der -text -noout
openssl x509 -in certificate.pem -text -noout

1.5.3  Extensiones relacionadas con certificados

        Es más probable que la extensión engañe a las personas. Además del sufijo .der o .pem, existen los siguientes sufijos comunes:

crt

Debe ser la abreviatura de certificado, que es común en los sistemas *nix, principalmente codificación PEM, y también puede ser codificación DER

cierto

Solicitud de firma de certificado, común en sistemas Windows, principalmente codificación DER, también puede ser codificación PEM

llave

La información clave almacenada por el usuario puede estar codificada por DER o codificada por PEM. Puede consultar PKCS#1 (RFC8017) para ver sus campos y definiciones específicos; sin embargo, el método de almacenamiento de texto sin formato de la clave es peligroso. Generalmente, el formato PKCS#8 (RFC5958) se usa para el almacenamiento cifrado, es decir, se establece una clave de extracción

rsc

La solicitud de emisión del certificado es similar al contenido del certificado, pero no contiene la información del emisor. El emisor genera un archivo de certificado basado en el csr y agrega su propia información de emisión. Para obtener más información, consulte (PKCS#10 RFC2314)

pfx/p12

Empaquete el certificado y la clave privada en un archivo y configure "extraer contraseña";

[Nota] PKCS12 no admite la configuración de la contraseña de entrada del almacén de claves, que es la misma que la contraseña del almacén de claves de forma predeterminada

jks

almacén de claves

almacén de confianza

jks (Java Key Storage) se usa comúnmente en aplicaciones relacionadas con JAVA. De hecho, es similar a PKCS12. Empaqueta el certificado y la clave privada juntos y establece la "contraseña de extracción". En cuanto al almacén de claves y el almacén de confianza, es solo una diferencia conceptual. El almacén de claves generalmente representa un certificado de usuario o servidor, mientras que el almacén de confianza generalmente representa un certificado de CA.

        Si quieres profundizar, puedes echar un vistazo a la familia de protocolos PKCS, la clave mencionada anteriormente, csr, pfx/p12, etc., son todas extensiones definidas en la familia de protocolos.

1.6  Ver certificado

1.6.1. ventanas

        En el menú Inicio Ejecutar, ingrese certlm.msc para administrar certificados para la computadora local, o certmgr.msc para administrar certificados para el usuario actual.

1.6.2. Androide

        Tome Honor como ejemplo, otros tipos de teléfonos móviles funcionan de manera similar. Busque "Certificado" en la configuración, puede encontrar "Instalar certificado" y "Credenciales de confianza". En Trusted Credentials, puede ver los certificados de "sistema" y "usuario actual", y los certificados correspondientes se pueden activar o desactivar en las dos listas.

        Puede instalar sus propios certificados en Instalar certificados. Esta operación es difícil y no se recomienda dejar que los usuarios la realicen solos.

2.  Generar un certificado raíz

2.1  Generar almacén de claves de certificado raíz

        El certificado raíz es un certificado autofirmado, y tanto el usuario como el emisor son ellos mismos. Utilice el siguiente comando para generar el almacén de claves del certificado raíz (si no se especifica la ruta del archivo del almacén de claves, se almacenará en .keystore en el directorio del usuario de forma predeterminada), ingrese la contraseña del almacén de claves y complete la información del certificado raíz.

keytool -genkeypair -validity 36500 -keyalg EC -keypass xxxxxx -storepass xxxxxx -dname "CN=njhx,C=CN,OU=njhx" -alias rootca -keystore root.jks

        Este comando utiliza el algoritmo de curva elíptica secp256r1 para generar un par de claves EC de 256 bits y guardarlo en njhx_root.jks. Utilice el siguiente comando para ver la información del almacén de claves y encontrará que tanto el editor como el propietario son njhx:

keytool -list -keystore root.jks -keypass xxxxxx -storepass xxxxxx -v

2.2  Exportar el certificado raíz desde el almacén de claves del certificado raíz

Utilice la función de exportación de keytool para exportar el certificado raíz del almacén de claves, introduzca la contraseña del almacén de claves y el archivo del certificado exportado es rootca.cer. El comando es el siguiente:

keytool -exportcert -validity 36500 -alias rootca -file root.cer -keystore root.jks -keypass xxxxxx -storepass xxxxxx

En este momento, tanto el emisor como el usuario son njhx

3.  Generar un certificado secundario

3.1  Generar un almacén de claves de certificado secundario

El certificado secundario debe estar firmado por el certificado raíz.

  • Primero use keytool para generar el almacén de claves del certificado secundario, pero todavía está autofirmado en este momento, necesitamos generar una solicitud de certificado secundario (que contiene la clave pública del certificado secundario);
  • Luego envíe la solicitud de certificado a la rootca para emitir el certificado secundario;
  • Finalmente, importamos el certificado secundario emitido por rootca al almacén de claves de certificados para completar la generación del certificado secundario.

        El siguiente comando es para generar un almacén de claves de certificado secundario. El nombre del almacén de claves es subca. En este momento, todavía está autofirmado, y el emisor del certificado y el usuario son ambos:

keytool -genkeypair -validity 36500 -keyalg EC -keypass yyyyyy -storepass yyyyyy -dname "CN=njhx.com,C=CN,OU=njhx" -alias subca -keystore sub.jks

3.2  Generar una solicitud de certificado desde el almacén de claves de certificado secundario

        Exporte la solicitud de certificado desde el almacén de claves de CA secundario, el siguiente es el comando para exportar la solicitud de certificado, subca es el nombre del almacén de claves de CA secundario generado anteriormente y, finalmente, exporte el archivo de solicitud de certificado como subca.csr:

keytool -certreq -alias subca -file sub.csr -keystore sub.jks -keypass yyyyyy -storepass yyyyyy

3.3  Usar el certificado raíz para emitir un certificado

Con la función de emisión de certificados de la herramienta keytool, use la rootca para emitir un certificado secundario a la solicitud de certificado secundario (subca.csr). El comando es el siguiente, alias especifica el emisor del certificado, infile especifica el archivo de solicitud de certificado y outfile es el nombre de archivo del certificado secundario:

keytool -gencert -validity 36500 -alias rootca -infile sub.csr -outfile sub.cer -keystore root.jks -keypass xxxxxx -storepass xxxxxx

        Puede ver que el emisor del certificado ya es njhx y el usuario es njhx.com

3.4  Importar el certificado secundario al almacén de claves

        Debido a que el almacén de claves generado localmente todavía está autofirmado, debe importar el certificado secundario emitido por el certificado raíz al almacén de claves en este momento. Antes de importar, primero debe importar el certificado raíz autofirmado al almacén de claves. Esto es muy importante, de lo contrario, informará "No se puede crear una cadena a partir de la respuesta", el comando es el siguiente:

keytool -importcert -alias rootca -file root.cer -keystore sub.jks -storepass yyyyyy -keypass yyyyyy

        Luego, sub.cer se puede importar al almacén de claves. alias subca es el alias del par de claves utilizado para generar el almacén de claves o la solicitud de certificado:

keytool -importcert -alias subca -file sub.cer -keystore sub.jks -storepass yyyyyy -keypass yyyyyy

        En este punto, verifique que el emisor del certificado del par de claves subca en el almacén de claves sea njhx en rootca.

keytool -list -alias subca -v -keystore sub.jks -storepass yyyyyy 

4.  Usar el certificado secundario para emitir certificados de usuario

        El proceso de emitir una CA de usuario es el mismo que el de generar una CA secundaria. A continuación, generamos la CA del usuario usuario, cambiamos la rootca en la operación de generar el certificado secundario a la subca del certificado secundario, y cambiamos el alias a usuario.

4.1  Generar almacén de claves de certificado de usuario

        Primero genere el almacén de claves de userca, el comando es el siguiente:

keytool -genkeypair -alias userca -keyalg EC -validity 36500 -keystore user.jks -keypass zzzzzz -storepass zzzzzz -dname "CN=*.mesh.njhx.com,C=CN,OU=njhx"

4.2  Generar solicitud de certificado de usuario

keytool -certreq -alias userca -file user.csr -keystore user.jks -keypass zzzzzz -storepass zzzzzz

4.3  Emisión de certificados de usuario con certificados secundarios

keytool -gencert -alias subca -infile user.csr -outfile user.cer -keystore sub.jks -keypass yyyyyy -storepass yyyyyy

4.4  Importar el certificado de usuario al almacén de claves

        Al importar el certificado de usuario, también debe importar el rootca , de lo contrario, cuando el cliente lo use, la verificación fallará.

keytool -importcert -alias userca -file user.cer -keystore user.jks -storepass zzzzzz
keytool -importcert -alias rootca -file root.cer -keystore user.jks -storepass zzzzzz

        Al ver el almacén de claves, muestra que la longitud de la cadena de certificados es 3.

4.5  Ver cadena de certificados de usuario

        Primero debe instalar el certificado raíz y el certificado secundario en el almacén de confianza de certificados de la computadora local y hacer doble clic en user.cer para ver que el certificado ya es de confianza y puede ver la relación de la cadena de certificados.

4.6  Convertir JKS a BKS

        Debido a que JKS no es compatible con Android (BouncyCastle se usa en la capa inferior de Android), es necesario convertir el archivo jks a BKS. Antes de convertir, debe descargar el paquete jar de BouncyCastle, como descargar "bcprov-jdk18on-1.71.1.jar", especifique el proveedor y la ruta del paquete jar en keytool, y use el siguiente comando para convertir:

keytool -importkeystore -alias userca -srckeystore user.jks -destkeystore user.bks -srcstoretype JKS -deststoretype BKS -srcstorepass zzzzzz -srckeypass zzzzzz -deststorepass zzzzzz -destkeypass zzzzzz -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath path_to_bcprov-jdk18on-1.71.1.jar

        Utilice el siguiente comando para ver el certificado user.bks y confirmar si la longitud de la cadena del certificado es 3:

keytool -list -v -keystore user.bks -storepass zzzzzz -keypass zzzzzz -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath path_to_bcprov-jdk18on-1.71.1.jar

5.  uso

5.1  Uso de certificados autofirmados en Java

5.1.1  Uso de certificados autofirmados en Netty

        El primero es crear SSLContext con el almacén de claves del usuario:

private SSLContext createSslContext() {
    try (InputStream inputStream = new FileInputStream(“path to user.jks”)) {
        ks = KeyStore.getInstance(“JKS”);
        //加载keytool生成的密钥库,其中包括证书链
        ks.load(inputStream, “zzzzzz”.toCharArray());
    } catch(Exception e) {
        LOG.warn("Fail to load keystore,can't support https", e);
        return null;
    }

    SSLContext sslContext = null;
    try {
        sslContext = SSLContext.getInstance("TLS");
        KeyManagerFactory kmf =         KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(this.serverKeyStore.keystore, this.serverKeyStore.keypass);
        sslContext.init(kmf.getKeyManagers(), null, null);
    } catch(Exception e) {
        LOG.error("Fail to create ssl context", e);
    }

    return sslContext;
}

Luego, cuando se inicialice netty, agregue SslHandler en la primera posición

SSLContext sslContext = createSslContext();
if(sslContext != null) {
    SSLEngine sslEngine = sslContext .createSSLEngine();
    sslEngine.setUseClientMode(false);
    pl.addLast("ssl", new SslHandler(sslEngine));
}

        Se debe prestar especial atención, si se utiliza BouncyCastle en el proyecto, al agregar el Proveedor, debe agregarse al final, de lo contrario, le indicará que la contraseña es incorrecta, aunque la contraseña seguramente será correcta.

Security.insertProviderAt(new BouncyCastleProvider(), Security.getProviders().length + 1);

5.1.2  Uso de certificados autofirmados en OkHttp

        Si no desea confiar en el certificado raíz, puede importar user.cer a KeyStore; al mismo tiempo, puede confiar en el nombre de dominio establecido en user.cer en hostnameVerifier.

CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
try(InputStream certificate = new FileInputStream("path to user.cer")) {
    keyStore.setCertificateEntry("userca", certificateFactory.generateCertificate(certificate));
}
//使用包含自签证书信息的keyStore构建一个X509TrustManager
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
    KeyManagerFactory.getDefaultAlgorithm()
);

keyManagerFactory.init(keyStore, null);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
    TrustManagerFactory.getDefaultAlgorithm()
);

trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
    throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}

        Cree un administrador de confianza y solo confíe en el almacén de claves creado por usted mismo

SSLContext sslContext = SSLContext.getInstance("TLS");
trustManagerFactory.init(keyStore);
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
OkHttpClient.Builder builder = new OkHttpClient.Builder()
    .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager)trustManagers[0])
    .hostnameVerifier((hostname, session) -> {
        try {
            Certificate[] certs = session.getPeerCertificates();
            if(certs != null && certs.length > 0) {
                X509Certificate cert = (X509Certificate)certs[0];
                String peer = cert.getSubjectX500Principal().getName();
                if(peer.contains(".mesh.njhx.com")) {
                    return true;
                }

                LOG.error("Fail to verify cert host name {}", peer);
            }
        } catch (SSLPeerUnverifiedException e) {
            LOG.error("Fail to get cert host name", e);
        }

        return false;
    });

        La implementación recomendada es confiar en el certificado raíz root.cer. En este caso, debe implementar X509TrustManager usted mismo:

private static class RootTruster implements X509TrustManager {
    private final X509Certificate certificate;

    public RootTruster(X509Certificate certificate) {
        this.certificate = certificate;
    }

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        // 双向认证才会用到
    }

    // 校验服务端证书是否合法
    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        if (chain == null || chain.length == 0) {
            throw new IllegalArgumentException("checkServerTrusted:x509Certificate array isnull");
        }
        X509Certificate c = chain[chain.length - 1]; //最后一个就是根证书
        if(c.equals(rootCer)) {
            return; //信任链的根证书就是预置的根证书,则不必抛出异常
        }
        throw new CertificateException("Root not supported,chain.length=" + chain.length);
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[] {certificate};
    }
}

        Luego coloque RootTruster en la lista TrustManager

// 加载根证书
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(“stream ofroot.cer”);
TrustManager[] trustManagers;
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init((KeyStore) null);

trustManagers = new TrustManager[tmf.getTrustManagers().length + 1];
// 创建一个trustmanager,只信任自建的keystore
trustManagers[0] = new RootTruster(certificate);
int i = 1;
for (TrustManager trustManager : tmf.getTrustManagers()) {
    trustManagers[i++] = trustManager;
}

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagers, SecureUtil.getRandom());
builder.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustManagers[0]);

5.2  Uso de certificados autofirmados en C#

        Debido a que el cliente de Windows en el proyecto se implementa mediante C#, es necesario confiar en el certificado raíz autoconstruido en C#. Al sobrecargar ServerCertificateValidationCallback, se puede juzgar que el certificado raíz es raíz, cer.

//受.net版本限制,此处最高只支持TLS1.2版本
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
WebRequestHandler handler = new WebRequestHandler();
X509Certificate2 rootCert = new X509Certificate2(“path to root.cer”); //本地根证书对象
handler.ServerCertificateValidationCallback += (sender, cert, chain, error) => {
    if (error == SslPolicyErrors.None) {
        return true;
    }

    if (!cert.Subject.Contains(CERT_DOMAIN)) {
        return false;
    }

    //最后一个证书是根证书
    X509Certificate2 lastCert = chain.ChainElements[chain.ChainElements.Count - 1].Certificate;
    //与本地根证书比较
    if (rootCert.Equals(lastCert)) {
        return true;
    }

    return false;
};

5.3  Uso de certificados autofirmados en Android

        En Android, ya sea como servidor o como cliente, la implementación es la misma que en Java. La única diferencia es que cuando el servidor carga server.jks, debe convertirse a server.bks.

5.4  Uso de certificados autofirmados en IE

5.4.1. ventanas

        Haga doble clic en el certificado raíz, seleccione el certificado de instalación en la ventana emergente y seleccione "Autoridades de certificación raíz de confianza" en la página de almacenamiento. Después de que la importación sea exitosa, sub.cer se mostrará normalmente; de ​​lo contrario, aparecerá un signo de exclamación.

        Al final, la prueba no tuvo éxito porque esta vez no se utilizó ningún navegador y no se realizaron más intentos. La apertura en el navegador Edge siempre se rechaza debido a problemas de seguridad.

6.  Resumen

        Todo el proceso de exploración tomó alrededor de una semana.Después de hacerlo de nuevo, tuve una comprensión más completa del certificado. Los proyectos típicos no utilizarán el contenido descrito en este artículo.

        Al explorar el contenido de este artículo, debe tener una comprensión básica de los algoritmos RSA y EC, y tener una comprensión clara del conocimiento relacionado con TLS/SSL, especialmente el proceso de intercambio de claves. De lo contrario, se sentirá abrumado ante tantas opciones.

Supongo que te gusta

Origin blog.csdn.net/flyinmind/article/details/126861506
Recomendado
Clasificación