Ich möchte selbstsignierte Zertifikate im Handumdrehen mit beliebigen Start- und Enddaten erstellen, einschließlich Enddaten in derVergangenheit. Ich würde lieber Standardtools verwenden, z. B. OpenSSL, aber alles, was die Arbeit erledigt, wäre großartig.
Die Stack Overflow-FrageWie erstelle ich ein OpenSSL-Zertifikat, das in weniger als einem Tag abläuft?stellt eine ähnliche Frage, aber ich möchte, dass mein Zertifikat selbstsigniert ist.
Falls Sie sich das fragen: Die Zertifikate werden für automatisierte Tests benötigt.
Antwort1
Bisher gab es zwei Möglichkeiten, Zertifikate zu erstellen. Entweder man fälschte die Uhrzeit (1)(2) oder man definierte beim Signieren des Zertifikats ein Zeitintervall (3).
1) Erstens, über das Fälschen der Zeit: Um ein Programm glauben zu lassen, es sei in einem anderen Datum als das System, schauen Sie sich an libfaketime
undfaketime
So installieren Sie es in Debian:
sudo apt-get install faketime
Sie würden dann faketime
vor dem openssl
Befehl verwenden.
Anwendungsbeispiele:
$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
Aus man faketime
:
Der angegebene Befehl wird dazu verleitet zu glauben, dass die aktuelle Systemzeit die im Zeitstempel angegebene ist. Die Wanduhr läuft ab diesem Datum und dieser Uhrzeit weiter, sofern nichts anderes angegeben wird (siehe erweiterte Optionen). Tatsächlich ist faketime ein einfacher Wrapper für libfaketime, der den LD_PRELOAD-Mechanismus verwendet, um eine kleine Bibliothek zu laden, die Systemaufrufe von Funktionen wie time(2) und fstat(2) abfängt.
In Ihrem Fall können Sie beispielsweise sehr gut das Jahr 2008 als Datum festlegen und dann ein Zertifikat mit einer Gültigkeit von 2 Jahren bis 2010 erstellen.
faketime '2008-12-24 08:15:42' openssl ...
Als Randbemerkung: Dieses Dienstprogramm kann in mehreren Unix-Versionen, einschließlich MacOS, als Wrapper für alle Arten von Programmen (nicht ausschließlich auf der Befehlszeile) verwendet werden.
Zur Klarstellung: Nur die Zeit der mit dieser Methode geladenen Binärdateien (und ihrer untergeordneten Elemente) wird geändert, und die falsche Zeit wirkt sich nicht auf die aktuelle Zeit des restlichen Systems aus.
2) Wie @Wyzard angibt, haben Sie auch das datefudge
Paket, dessen Verwendung sehr ähnlich ist faketime
.
Da es Unterschiede gibt, datefudge
hat es keinen Einfluss fstat
(d. h. es ändert nicht die Erstellungszeit der Datei). Es hat auch seine eigene Bibliothek, datefudge.so, die es mit LD_PRELOAD lädt.
Es gibt auch ein -s
static time
, bei dem die referenzierte Zeit immer zurückgegeben wird, unabhängig davon, wie viele zusätzliche Sekunden vergangen sind.
$ datefudge --static "2007-04-01 10:23" sh -c "sleep 3; date -R"
Sun, 01 Apr 2007 10:23:00 +0100
3) Neben der Zeitfälschung können Sie noch einfacher den Start- und den Endzeitpunkt der Gültigkeit des Zertifikats festlegen, wennUnterzeichnungdas Zertifikat in OpenSSL.
Das Missverständnis bei der Frage, auf die Sie in Ihrer Frage verweisen, besteht darin, dass die Gültigkeit des Zertifikats nicht zum Zeitpunkt der Anforderung (bei der CSR-Anforderung), sondern bei der Signierung definiert wird.
Wenn Sie openssl ca
zum Erstellen des selbstsignierten Zertifikats verwenden, fügen Sie die Optionen -startdate
und hinzu -enddate
.
Das Datumsformat in diesen beiden Optionen openssl/crypto/x509/x509_vfy.c
ist laut OpenSSL-Quellen unter ASN1_TIME, auch bekannt als ASN1UTCTime: Das Format muss entweder JJMMTTTHMMSSZ oder JJJJMMTTTHMMSSZ sein.
Zitat 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." */
Und aus dem Änderungsprotokoll (Fehler 2038?) – Dieses Änderungsprotokoll dient lediglich als zusätzliche Fußnote, da es nur diejenigen betrifft, die die API direkt verwenden.
Änderungen zwischen 1.1.0e und 1.1.1 [xx XXX xxxx]
*) Fügen Sie die ASN.1-Typen INT32, UINT32, INT64, UINT64 und Varianten mit dem Präfix Z hinzu. Diese sollen LONG und ZLONG ersetzen und größensicher sein. Von der Verwendung von LONG und ZLONG wird abgeraten, und ihre Verwendung ist in OpenSSL 1.2.0 geplant.
Die Erstellung eines Zertifikats für den Zeitraum vom 1. Januar 2008 bis zum 1. Januar 2010 kann folgendermaßen erfolgen:
openssl ca -config /path/to/myca.conf -in req.csr -out ourdomain.pem \
-startdate 200801010000Z -enddate 201001010000Z
oder
openssl ca -config /path/to/myca.conf -in req.csr -out ourdomain.pem \
-startdate 0801010000Z -enddate 1001010000Z
-startdate
und -enddate
erscheinen in den openssl
Quellen und im Änderungsprotokoll. Wie @guntbert bemerkte, erscheinen sie zwar nicht auf der Hauptseite man openssl
, aber auch in 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).
Zitat openssl/CHANGE
:
Änderungen zwischen 0.9.3a und 0.9.4 [09. August 1999]
*) Korrigieren Sie die Argumente -startdate und -enddate (die fehlten) für das Programm „ca“.
PS Was die gewählte Antwort desFrageSie verweisen auf StackExchange: es ist im Allgemeinen einschlechte Ideeum die Systemzeit zu ändern, insbesondere in Produktionssystemen; und für die Methoden in dieser Antwort benötigen Sie bei der Verwendung keine Root-Rechte.
Antwort2
Ich bin fast überrascht, dass das Naheliegende funktioniert: Während openssl
als Argument die Anzahl der Tage verwendet wird, für die das Zertifikat gültig sein soll, geben Sie einfach eine negative Zahl an!
openssl req -x509 -newkey rsa:4096 \
-keyout key.pem -out cert.pem -days -365
Beachten Sie, dass dies tatsächlich zu etwas sehr Seltsamem führt: einem Zertifikat, dessen Ablaufzeitstempelgeht voraussein Zeitstempel für den Gültigkeitsbeginn. Ich empfehle nicht, dies für Ihre automatisierten Tests zu verwenden, da es seltsam ist. Sie möchten wahrscheinlich auch eine Möglichkeit, den Zeitstempel für den Gültigkeitsbeginn rückzudatieren.
Antwort3
Oder Sie könnten etwas wie dieses kurze Python-Programm verwenden ... (mit Vorbehalt)
Es erstellt einen Schlüssel (test.key) und ein Zertifikat (test.crt) mit einem Beginnzeitpunkt vor 10 Jahren (-10*365*24*60*60 Sekunden sind -10 Jahre) und einem Ablaufzeitpunkt vor 5 Jahren (-5*365*24*60*60).
Bitte beachten Sie, dass es sich um ein minimales Demonstrationsprogramm handelt. Es macht sich daher nicht die Mühe, Erweiterungen festzulegen (z. B. „basicConstraints“) und verwendet eine feste Seriennummer.
#!/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))
Antwort4
Schritt 1.Installieren Sie Faketime
sudo apt-get install faketime
Schritt 2.Erstellen Sie einen Tag vor dem aktuellen Datum ein abgelaufenes Zertifikat.
faketime 'last friday 5 pm' /bin/bash -c 'openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 6 -nodes'
Schritt 3Überprüfen des Gültigkeitsdatums des Zertifikats
openssl x509 -noout -text -in cert.pem