OpenSSL: Mostrar parámetros DH

15

Cuando se utilizan cifrados SSL que se basan en un intercambio de claves Hellman diferente, el tamaño de la clave privada empleada es de crucial importancia para la seguridad de ese intercambio de claves.

Cuando me conecto a un servidor usando la herramienta "openssl s_client", ¿cómo puedo consultar los parámetros DH utilizados?


fuente

Respuestas:

17

No conozco un interruptor de línea de comandos fácil de usar, pero en la openssl s_clientlínea de comandos, puede agregar la -msgopción para obtener un volcado hexadecimal del mensaje de protocolo de enlace. Luego busca el ServerKeyExchangemensaje; Debe tener un aspecto como este:

<<< TLS 1.2 Handshake [length 030f], ServerKeyExchange
    0c 00 03 0b 01 00 ff ff ff ff ff ff ff ff c9 0f
    da a2 21 68 c2 34 c4 c6 62 8b 80 dc 1c d1 29 02
    4e 08 8a 67 cc 74 02 0b be a6 3b 13 9b 22 51 4a
    (...)

y se lee de esa manera:

  • 0c 00 03 0b: mensaje de tipo "ServerKeyExchange" (ese es el "0c") de longitud 0x00030B bytes.
  • El primer elemento es el módulo DH como un entero grande, con un encabezado de dos bytes de longitud. Aquí, la longitud se codifica como 01 00, lo que significa un número entero codificado sobre 0x0100 bytes. Eso es 256 bytes, por lo que el módulo tiene una longitud entre 2041 y 2048 bits.
  • Los bytes del módulo siguen, en orden big-endian sin signo. Los bytes superiores de ese módulo son, en este caso ff ff ff ff...,. El módulo tiene una longitud exactamente de 2048 bits.

Si usa un conjunto de cifrado ECDHE (curva elíptica), entonces el ServerKeyExchangeformato es diferente, por supuesto.

Vea el estándar para la definición del ServerKeyExchangemensaje. Para los conjuntos de cifrado DHE, contiene el módulo p , el generador gy la clave pública DH del servidor y , en ese orden, cada uno expresado como un entero grande en el formato descrito anteriormente (encabezado de 16 bits que contiene la longitud en bytes, luego el entero valor en codificación big-endian sin signo).

Las versiones recientes de OpenSSL tienden a seleccionar un tamaño de módulo DH que coincida (desde un punto de vista de seguridad) con la fuerza del par de claves del servidor (utilizado para firmar el ServerKeyExchangemensaje). En el ejemplo anterior, el servidor tiene una clave RSA de 2048 bits, por lo que OpenSSL eligió usar un módulo DH de 2048 bits (en este caso, el módulo conocido descrito en RFC 3526, sección 3 ).

Algunos otros servidores se adhieren a grupos DH de 1024 bits para garantizar la compatibilidad con algunos clientes existentes que no admiten grupos DH más grandes (el mayor infractor es la implementación de SSL en Java, corregida en Java 8 build 56 en 2012). Una falla conocida en el protocolo TLS, para los conjuntos de cifrado DHE, es que el cliente no tiene forma de especificar qué tamaño de módulo puede admitir (esto se corrige para ECDHE, porque el cliente puede especificar la lista exacta de curvas que acepta) .

Thomas Pornin
fuente
1
OpenSSL no selecciona automáticamente DHE, pero puede una devolución de llamada de la aplicación. OpenSSL 1.0.2 (enero de 2015) opcionalmente puede seleccionar automáticamente ECDHE , y también en 1.0.2 s_clientsiempre muestra "Tecla del servidor temporal" DH y tamaño o ECDH y curva cuando corresponde, justo antes de "apretón de manos ha leído xy escrito y", por lo que ya no necesita para decodificarlo Es reciente Apache mod_ssl que selecciona automáticamente DHE: httpd.apache.org/docs/trunk/mod/mod_ssl.html#sslcertificatefile (que señala el problema sobre los clientes Java).
dave_thompson_085
Yo uso 1.0.1e de OpenSSL y no consigo ninguna ServerKeyExchangecon 0c 00 03 0b. ¿Puedes proporcionar el comando exacto para obtener la salida? No tengo ninguno de los 0c
apretones de
Si el conjunto de cifrado seleccionado por el servidor no es un conjunto de cifrado "DHE" o "ECHDE", no habrá ningún mensaje ServerKeyExchange.
Thomas Pornin
Obtengo <<< TLS 1.2 Handshake [longitud 01cd], ServerKeyExchange 0c 00 01 c9 03 00 17 41 04 08 5f 82 88 1e e5 b6 seguido de 443 octetos que corresponden a una longitud de 0x1c9 que comienza en el quinto octeto. Sin embargo, "0300" parece significar 768 octetos mientras estoy seguro de que mi parámetro DH es "solo" 2048 bits.
Ley29
1
@ Law29 Esto se parece más a un ECDHE ServerKeyExchange. Si usa una curva elíptica, entonces "03" significa "esta es una curva con nombre, los siguientes dos bytes codifican el identificador de curva". Entonces "00 17" es el identificador de curva, que es NIST P-256 (la curva más utilizada para ECDHE). Entonces "41" es la longitud del punto público, que es exactamente el valor correcto para un punto P-256 en formato sin comprimir; dicho punto comenzaría con un byte de valor 0x04, y eso es precisamente lo que tiene. En resumen: parece que su apretón de manos TLS 1.2 realmente usa ECDHE, no DHE.
Thomas Pornin
9

Si tiene el certificado en formato PEM, puede probar este comando, debería darle una salida adecuada del comando Openssl.

openssl dhparam -inform PEM -in ./imapd.pem -check -text

(Salida de muestra)
    Parámetros de PKCS # 3 DH: (512 bit)
        principal:
            xx: xx: xx: xx
            xx: xx: xx: xx
            xx: xx: xx: xx
        generador: 2 (0x2)
Los parámetros de DH parecen estar bien.
----- COMIENCE LOS PARÁMETROS DH -----
XXXX
XXXX
----- FIN DE PARÁMETROS DH -----

Espero que esto sea lo que estás buscando.

David Loh
fuente