Cree un certificado autofirmado con fecha de finalización anterior

Cree un certificado autofirmado con fecha de finalización anterior

Me gustaría crear certificados autofirmados sobre la marcha con fechas de inicio y finalización arbitrarias, incluidas fechas de finalización en elpasado. Preferiría utilizar herramientas estándar, por ejemplo, OpenSSL, pero cualquier cosa que haga el trabajo sería genial.

La pregunta de desbordamiento de pila¿Cómo generar un certificado openssl con vencimiento menor a un día?hace una pregunta similar, pero quiero que mi certificado esté autofirmado.

En caso de que se lo pregunte, los certificados son necesarios para realizar pruebas automatizadas.

Respuesta1

Tiene dos formas de crear certificados en el pasado. Ya sea falsificando la hora (1)(2), o definiendo el intervalo de tiempo al firmar el certificado (3).

1) En primer lugar, sobre falsificar la hora: para hacer que un programa piense que está en una fecha diferente a la del sistema, eche un vistazo libfaketimeyfaketime

Para instalarlo en Debian:

sudo apt-get install faketime

Luego lo usarías faketimeantes del opensslcomando.

Para ejemplos de uso:

$faketime 'last friday 5 pm' /bin/date
Fri Apr 14 17:00:00 WEST 2017
$faketime '2008-12-24 08:15:42' /bin/date
Wed Dec 24 08:15:42 WET 2008

De man faketime:

Se engañará al comando dado haciéndole creer que la hora actual del sistema es la especificada en la marca de tiempo. El reloj de pared seguirá funcionando a partir de esta fecha y hora a menos que se especifique lo contrario (ver opciones avanzadas). En realidad, faketime es un contenedor simple para libfaketime, que utiliza el mecanismo LD_PRELOAD para cargar una pequeña biblioteca que intercepta llamadas del sistema a funciones como time(2) y fstat(2).

Entonces, por ejemplo, en su caso, puede definir una fecha de 2008 y luego crear un certificado con una validez de 2 años hasta 2010.

faketime '2008-12-24 08:15:42' openssl ... 

Como nota al margen, esta utilidad se puede utilizar en varias versiones de Unix, incluido MacOS, como contenedor para cualquier tipo de programa (no exclusivo de la línea de comandos).

Como aclaración, solo a los binarios cargados con este método (y sus hijos) se les cambia la hora, y la hora falsa no afecta la hora actual del resto del sistema.

2) Como afirma @Wyzard, también tienes el datefudgepaquete que es muy similar en uso a faketime.

Como diferencias, datefudgeno influye fstat(es decir, no cambia la hora de creación del archivo). También tiene su propia biblioteca, datefudge.so, que se carga usando LD_PRELOAD.

También tiene un -s static timemodo en el que siempre se devuelve el tiempo al que se hace referencia a pesar de cuántos segundos adicionales hayan pasado.

$ datefudge --static "2007-04-01 10:23" sh -c "sleep 3; date -R"
Sun, 01 Apr 2007 10:23:00 +0100

3) Además de falsificar la hora, y más simplemente, también puedes definir el punto de inicio y el punto final de validez del certificado cuandofirmael certificado en OpenSSL.

La idea errónea de la pregunta a la que se vincula en su pregunta es que la validez del certificado no se define en el momento de la solicitud (en la solicitud del CSR), sino al firmarlo.

Cuando lo utilice openssl capara crear el certificado autofirmado, agregue las opciones -startdatey -enddate.

El formato de fecha en esas dos opciones, según las fuentes de openssl en openssl/crypto/x509/x509_vfy.c, es ASN1_TIME, también conocido como ASN1UTCTime: el formato debe ser AAAAMMDDHHMMSSZ o AAAAMMDDHHMMSSZ.

Citando openssl/crypto/x509/x509_vfy.c:

int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
{
    static const size_t utctime_length = sizeof("YYMMDDHHMMSSZ") - 1;
    static const size_t generalizedtime_length = sizeof("YYYYMMDDHHMMSSZ") - 1;
    ASN1_TIME *asn1_cmp_time = NULL;
    int i, day, sec, ret = 0;

    /*
     * Note that ASN.1 allows much more slack in the time format than RFC5280.
     * In RFC5280, the representation is fixed:
     * UTCTime: YYMMDDHHMMSSZ
     * GeneralizedTime: YYYYMMDDHHMMSSZ
     *
     * We do NOT currently enforce the following RFC 5280 requirement:
     * "CAs conforming to this profile MUST always encode certificate
     *  validity dates through the year 2049 as UTCTime; certificate validity
     *  dates in 2050 or later MUST be encoded as GeneralizedTime."
     */

Y del registro de CAMBIOS (¿error 2038?): este registro de cambios es solo una nota a pie de página adicional, ya que solo concierne a aquellos que usan directamente la API.

Cambios entre 1.1.0e y 1.1.1 [xx XXX xxxx]

*) Agregue los tipos ASN.1 INT32, UINT32, INT64, UINT64 y variantes con el prefijo Z. Están destinados a reemplazar LONG y ZLONG y a tener un tamaño seguro. Se desaconseja el uso de LONG y ZLONG y está previsto que queden obsoletos en OpenSSL 1.2.0.

Así, la creación de un certificado del 1 de enero de 2008 al 1 de enero de 2010, se puede realizar de la siguiente manera:

openssl ca -config /path/to/myca.conf -in req.csr -out ourdomain.pem \
-startdate 200801010000Z -enddate 201001010000Z

o

openssl ca -config /path/to/myca.conf -in req.csr -out ourdomain.pem \
-startdate 0801010000Z -enddate 1001010000Z

-startdatey -enddateaparecen en las opensslfuentes y en el registro de CAMBIOS; como señaló @guntbert, si bien no aparecen en la man opensslpágina principal, también aparecen en man ca:

-startdate date
       this allows the start date to be explicitly set. The format of the date is
       YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure).

   -enddate date
       this allows the expiry date to be explicitly set. The format of the date is
       YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure).

Citando openssl/CHANGE:

Cambios entre 0.9.3a y 0.9.4 [9 de agosto de 1999]

*) Se corrigieron los argumentos -startdate y -enddate (que faltaban) en el programa 'ca'.

PD: En cuanto a la respuesta elegida delpreguntahace referencia desde StackExchange: generalmente es unmala ideacambiar la hora del sistema, especialmente en los sistemas de producción; y con los métodos de esta respuesta no necesitas privilegios de root al usarlos.

Respuesta2

Casi me sorprende descubrir que lo obvio funciona: mientras que openssltoma como argumento el número de días durante los cuales el certificado debería ser válido, ¡simplemente proporcione un número negativo!

openssl req -x509 -newkey rsa:4096 \
    -keyout key.pem -out cert.pem -days -365

Tenga en cuenta que esto en realidad resulta en algo muy extraño: un certificado cuya marca de tiempo de vencimientoprecedesu marca de tiempo de inicio de validez. En realidad, no recomiendo que uses esto para tus pruebas automatizadas, ya que es extraño. Probablemente también desee una forma de retroceder la marca de tiempo de inicio de validez.

Respuesta3

O podrías usar algo como este breve programa de Python... (se aplican advertencias)

Crea una clave (test.key) y un certificado (test.crt) con un tiempo de inicio hace 10 años (-10*365*24*60*60 segundos es -10 años) y un tiempo de caducidad hace 5 años. (-5*365*24*60*60).

Tenga en cuenta que es un programa de demostración mínimo, por lo que no se molesta en establecer ninguna extensión (por ejemplo, basicConstraints) y utiliza un número de serie fijo.

#!/usr/bin/env python

from OpenSSL import crypto

key = crypto.PKey()
key.generate_key(crypto.TYPE_RSA, 2048)
cert = crypto.X509()
cert.get_subject().CN = "Test"
cert.set_serial_number(666)
cert.gmtime_adj_notBefore(-10*365*24*60*60)
cert.gmtime_adj_notAfter(-5*365*24*60*60)
cert.set_issuer(cert.get_subject())
cert.set_pubkey(key)
cert.sign(key, 'sha384')

open("test.crt", "wb").write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
open("test.key", "wb").write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key))

Respuesta4

Paso 1.instalar tiempo falso

sudo apt-get install faketime

Paso 2.Generar certificado caducado un día antes de la fecha actual.

faketime 'last friday 5 pm' /bin/bash -c 'openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 6 -nodes'

Paso 3Verificar la fecha de validez del certificado

openssl x509 -noout -text -in cert.pem

Fechas de validez del certificado: captura de pantalla

información relacionada