Red de conocimiento informático - Aprendizaje de programación - Utilice openssl en Linux para detectar la validez del certificado de firma digital del archivo PE.

Utilice openssl en Linux para detectar la validez del certificado de firma digital del archivo PE.

La primera trampa: fecha de vencimiento

Windows no verifica la fecha de vencimiento del certificado al determinar si es válido. Incluso si el certificado excede la fecha de vencimiento por varios años, Microsoft aún lo considera válido siempre y cuando. ya que el certificado no ha sido revocado. Sin embargo, la función X509_verify_cert proporcionada en openssl puede verificar la validez del certificado, por lo que debe comentar la parte del código que verifica la validez y luego volver a compilar openssl...

Bien, descargue el última versión del sitio web de openssl, bueno, sigue siendo la versión 1.0.1g, que acaba de solucionar la vulnerabilidad Heartbleed...

Descargue, descomprima, vea el documento de INSTALACIÓN e intente compilarlo primero:

./config

make

Buena suerte, no necesitas instalar ninguna dependencia al compilar. Agregue libcrypto.a generado en el directorio raíz del código al proyecto y pruébelo. Está bien, comencemos ~

Busque la función X509_verify_cert en la línea 153 de crypto/x509/x509_vfy.c (consulte). Contenido en línea), la variable local ok almacenará en caché si se pasa cada paso de verificación y lo llamará en secuencia:

Crypto/x509/x509_vfy.c La línea 153 llama a la función X509_verify_cert (ver contenido en línea). Llama a:

check_issued

check_chain_extensions

check_name_constraints

check_trust

check_revocation

internal_verify

check_policy

Cuando internal_verify (ver en línea) verifica la validez del certificado, vaya a esa función y busque este código en la línea 1654:

ok = check_cert_time( ctx, xs);

if (!ok)

goto end;

Verifique la función check_cert_time para confirmar que está verificando notBefore y notAfter, así que comente Si elimina las tres líneas de código anteriores, la verificación del certificado no verificará la fecha de vencimiento.

Luego vuelva a compilar openssl e integre libcrypto.a en el proyecto~

La segunda trampa: extensión crítica no controlada

Después de buscar, encontré el siguiente contenido en el sitio web oficial de openssl:

-ignore_ criticy

-ignore_cert_time la función comprueba notBefore y notAfter. critic

Normalmente, un certificado será rechazado si hay extensiones críticas no controladas que OpenSSL no admite (como lo requiere RFC5280).

Normalmente, se rechazará la carga de los certificados si hay extensiones críticas no controladas que no son compatibles con OpenSSL (como lo requiere RFC5280).

Al buscar -ignore_critical, encontré el siguiente fragmento de código en verificar.c:

"...".

c:

else if (strcmp(*argv, "-ignore_critical") == 0)

vflags |= X509_V_FLAG_IGNORE _CRITICAL;

Luego use X509_STORE_set_flags función Establecer bits de bandera:

X509_STORE *ctx;

...

X509_STORE_set_flags(ctx, vflags

Eso es todo.

La tercera trampa: Error en la firma del certificado

Esta trampa no se puede solucionar, openssl dijo:

7 X509_V_ERR_CERT_SIGNATURE_FAILURE: Error en la firma del certificado

La firma del certificado no es válida.

Exporte el archivo del certificado en Windows y use openssl para verificarlo directamente. Se producirá un error al cargar el certificado y PEM_read_bio_X509 devuelve nulo....

Trampa 4: El certificado es revocado explícitamente por su emisor.

El certificado ha sido revocado explícitamente por su emisor. Esta es una herramienta proporcionada por Sysinternals, sigcheck.exe. El resultado de sigcheck.exe es que el emisor ha revocado explícitamente el certificado.

Bien, simplemente descargue el archivo de la lista de certificados de revocación de acuerdo con la URL proporcionada por el punto de distribución de CRL en el certificado y luego configure la lista de certificados de revocación para que se complete antes de llamar a X509_verify_cert para verificar la cadena de certificados:

X509_CRL *d2i_X509_CRL_fp(FILE_CRL_fp(FILE_FILE_CRL_fp)).CRL_fp(FILE *fp, X509_CRL **crl); // Leer la lista de certificados revocados

STACK_OF(X509_CRL) *sk_X509_CRL_new_null ();

#define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val)); // sk_X509_CRL_push(STACK_OF(X509_CRL) *crls, X509_CRL *crl);

void Verificar la cadena de certificados.

Rellenar la cuarta trampa conducirá a la quinta trampa (cómo obtener la lista de revocación) y a la sexta trampa (después de configurar el bit de bandera para detectar la lista de revocación, si el certificado no tiene una revocación). lista, informará un error directamente)...

La quinta trampa: obtener el archivo de lista de certificados revocados

El punto de distribución CRL en el certificado es un atributo extendido, PKCS # 7: Sintaxis de mensajes criptográficos V1. No se describe en 5.

Encontré estas preguntas y respuestas en StackOverflow Openssl: Cómo verificar si un certificado está revocado, donde la segunda respuesta dice que las CRL están definidas en RFC 5280, además de la lista de certificados revocados adjunta al certificado. son listas de certificados de revocación que utilizan el protocolo OCSP, e incluso las listas de certificados de revocación se dividen en listas de certificados de revocación que utilizan URL. Incluso las listas de revocación de certificados se dividen en puntos de distribución utilizando URL y LDAP DN (), consideremos el caso de utilizar URL como puntos de distribución de CRL.

Sin embargo, openssl no proporciona una API para obtener directamente la URL del punto de distribución de CRL, y la respuesta menciona que el módulo mod_ssl de Apache tiene un código de implementación para la detección local de CRL y OCSP, pero no explica dónde está. Se utiliza para la detección. Implementación utilizando URL como puntos de distribución de CRL.

Luego, encontré el código certextensions.c en frank4dd.com, que proporciona un programa de muestra sobre cómo usar openssl para extraer extensiones de certificados X.509v3, gracias a Frank4DD~~ ~~

Una vez que llegue a este punto, puede utilizar su programa de muestra para extraer las extensiones del certificado X.509v3.

Una vez que llegue aquí, puede usar directamente su programa de muestra para encontrar la URL del punto de distribución de CRL según el nombre completo y el URI de la palabra clave, o puede ver cómo openssl extrae la URL e implementarla usted mismo. una interfaz.

Si desea utilizar el segundo método, compile una versión de depuración de la biblioteca openssl, luego depure y siga los pasos de la función X509V3_EXT_print paso a paso hasta el final de la función GENERAL_NAME_print... Luego conoceremos la distribución de CRL. El número de URL del punto es 6, que es GEN_URI, por lo que obtenemos el resultado directamente.

La sexta trampa: período de validez de la CRL

En un entorno Windows, cada vez que se verifica la firma digital de un archivo PE, Windows descargará una lista de certificados revocados de la distribución CRL. En términos generales, el período de validez de cada CRL es muy corto, solo entre 5 y 20 días. Período de validez, sin embargo, nos resulta imposible descargar la lista de revocación más reciente desde el punto de distribución de CRL cada vez que verificamos una firma digital como lo hace Windows.

Además, Windows no invalidará la cadena de certificados cuando encuentre una CRL vencida, pero openssl no puede verificar la cadena de certificados cuando encuentre una CRL vencida, por lo que su validez se ignora al cargar y verificar la CRL. .

Al analizar el código fuente de openssl, X509_verify_cert llama a check_revocation, luego llama a check_cert y luego llama a check_crl. En esta función, hay un código para detectar el período de validez de la CRL:

if (. !(ctx-gt ;current_crl_score & CRL_SCORE_TIME))

{

ok = check_crl_time(ctx, crl, 1);

if (!ok)

goto err;

}

Las comprobaciones de validez de CRL se pueden ignorar mediante comentarios.

La séptima trampa: una lista de CRL vacía hará que openssl piense que la CRL no está cargada

9 Secuencia de inicialización

10 Nombre del certificado: key_id

p>