Inhaltsverzeichnis
Ziel der Anwendung
Für das bequeme und schnelle Anfragen von Zertifikaten an einer internen Windows Zertifizierungsstelle existieren aus meiner Sicht keine geeigneten Tools. Mit der grafischen Oberfläche mmc kann man natürlich manuell Zertifikate für den eigenen Benutzer und den lokalen Computer anfragen. Aber sehr oft benötige ich Zertifikate für andere Geräte. Nach dem Ausstellen mit der mmc muss das Zertifikat also erst als PFX-Datei im pkcs12-Format inklusive Private Key exportiert werden. Und wenn dann noch eine Konvertierung und eine Zerlegung in eine PEM- und eine KEY-Datei erforderlich wird, dann wird es schnell kompliziert. Dafür geht es in der cmd mit openssl.exe weiter…
Ebenso kann ein Certificate Signing Request von einem Drittsystem grafisch nur in der Zertifizierungsstelle selber eingereicht werden. Dann muss aber das signierte Zertifikat manuell aus der Datenbank der CA in eine CER-Datei exportiert werden.
Natürlich gibt es auch den cmd-Befehl certreq.exe, aber die Verwendung ist nicht sehr intuitiv. Also ist das auch keine Option für die Masse der Administratoren, die ein Zertifikat für ihren Service oder ihr Device benötigen, aber wenig Erfahrung mit Zertifizierungsstellen haben.
Für mich waren diese Gründe der Anlass, ein PowerShell-Script zu schreiben, dass die Vorteile der cmd-Befehle certreq.exe und openssl.exe einfach anspricht. Und damit der Komfort nicht auf der Strecke bleibt und cmd-Befehle durch PowerShell-Befehle ersetzt werden, rendert mein Script eine grafische Oberfläche.
Bestandteile
Das Script selber besteht aus einer ps1-Datei mit der Befehlslogik und einer ini-Datei, in der Variablen angepasst werden können. Der Vorteil der ini-Datei ist klar: Die PowerShell-Scriptdatei kann bei einem Update leichter ausgetauscht werden, da individuelle Anpassungen darin nicht notwendig sind. Diese befinden sich ja in der ini-Datei. Ebenso könnte man das Script auch digital signieren, da es vom Anwender nicht verändert werden muss.
Beide Dateien können in einem beliebigen Verzeichnis abgelegt werden. Wichtig ist nur, dass beide nebeneinander liegen und nicht umbenannt werden. Das Verzeichnis Certificates kann manuell erstellt werden. Es wird später die ausgestellten Zertifikate enthalten. Sollte es beim Scriptstart fehlen, dann wird es automatisch erzeugt:
Für den Start ist die Konfigurationsdatei wichtig:
Vergleicht man die geforderten Werte mit den angezeigten Werten der GUI zur Laufzeit, dann werden viele Eingaben sich selbst erklären:
Das sind die Werte im Detail
Eigenschaft | gültige Werte | Beschreibung |
---|---|---|
DefaultTemplate |
<String> |
Der Name der Zertifikatvorlage, die voreingestellt werden soll. Ist der Benutzer für diese Vorlage nicht berechtig, bleibt das Feld in der GUI leer. Will der Benutzer ein anderes Template wählen, dann ist das zur Laufzeit durch das DropDown-Feld möglich. |
Organization |
<String> |
Angabe zum Antragsteller: Firma |
OrganizationalUnit |
<String> |
Angabe zum Antragsteller: Abteilung |
Locality |
<String> |
Angabe zum Antragsteller: Ort |
State |
<String> |
Angabe zum Antragsteller: Bundesland |
Country |
<String> |
Angabe zum Antragsteller: Land |
|
<String> |
Angabe zum Antragsteller: Mailadresse |
KeyLength |
2048, 4096 |
Standardwert für die Schlüssellänge. Wird durch die Auswahl einer Zertifikatvorlage durch deren Wert zu Laufzeit überschrieben. |
KeyExportable |
true, false |
Export-Markierung des Private Keys. Wird durch Vorgaben der Zertifikatvorlage überschrieben. Beim Wert true wird eine PFX-Datei und ggf. eine KEY-Datei erstellt. |
DefaultMode |
SubmitCSR, CreateCSR |
Die GUI hat 2 Eingabeoptionen: manuell können Werte zur Erstellung eines CSR eingegeben werden. Alternativ kann ein fertiger CSR eingelesen werden. Die Auswahl kann zur Laufzeit überschrieben werden. |
AutoElevation |
true, false |
Manche Infrastrukturen verwenden die Certificate Templates mit dem Default-Security-Einstellungen. Dann haben Domain Admins die Enroll-Berechtigung. Dafür muss aber der Requestor-Prozess „als Admin“ ausgeführt werden. Mit dieser Einstellung prüft das Script, ob es elevated gestartet wurde. Ist das nicht der Fall, dann wird die UAC verwendet, um die erforderlichen Rechte anzufragen. |
ExportKey |
true, false |
Erstellt eine KEY-Datei mit dem Private Key. Benötigt openssl.exe |
ExportPEM |
true, false |
Erstellt eine PEM-Datei mit dem Public Key. Benötigt openssl.exe |
OpenSSLpath |
<String> ohne Leerzeichen |
Das Verzeichnis, in dem sich die Anwendung openssl.exe befindet. Leerzeichen sind nicht erlaubt, daher bei Bedarf die 8.3-Schreibweise verwenden. |
Ausstellen eines Zertifikates ohne openssl.exe
Das Script wird einfach über die PowerShell gestartet. Dafür bieten sich natürlich auch Verknüpfungen an:
Es werden eine Reihe von Abfragen im Hintergrund ausgeführt. Dabei ermittelt das Script über simple LDAP-Abfragen zu einem Domain Controller
- welche Certificate Templates im Active Directory registriert sind.
- Gleichzeitig wird analysiert, für welche Zertifikatvorlagen der verwendete Benutzer-Account das Enroll-Recht besitzt
- Und natürlich werden die dazugehörigen Enrollment-Services erkannt. Das sind dann die ausstellenden Zertifizierungsstellen
Alle Informationen werden in der GUI dargestellt. Ebenso werden Voreinstellungen aus der ini-Datei gelesen:
Der Admin kann nun den Dialog von oben nach unten bearbeiten. Üblicherweise wird zuerst die Vorlage gewählt, mit welcher das Zertifikat erstellt werden soll. In meiner LAB-Umgebung habe ich 3 Templates mit Enroll-Permission:
Die gelb hinterlegten Felder sind dabei Pflichtfelder. Wird ein Pflichtfeld mit einem Wert belegt, dann ändert sich die Farbe. Nachdem das Template ausgewählt wurde, geht es mit dem CommonName weiter. Natürlich könnte man auch einen Enrollment-Service auswählen, wenn mehrere zur Verfügung stehen. Der CommonName ist das wichtigste Element für Webserver-Zertifikate. Mein Script erstellt dabei automatisch ein SAN-Zertifikat und nutzt den CommonName zusätzlich als DNS-Subject. Weitere Subject Alternative Names (SAN) können im mehrzeiligen Feld mit einem Wert je Zeile angegeben werden. Beispiele werden mit dem Schalter „show samples“ dargestellt:
Ich definiere für meine Demo den CommonName test.ws-its.de. Daraus wird automatisch der SAN DNS=test.ws-its.de. Zusätzlich definiere ich noch den SAN DNS=test1.ws-its.de:
Im vorherigen Bild sieht man auch die vielen Antragsteller-Felder. Diese sind durch die ini-Datei mit Standardwerten vorbefüllt. Natürlich kann man die Werte vor dem Ausstellen auch anpassen. Die Schlüssellänge ist durch die Auswahl des Templates vorbefüllt und kann beibehalten oder ggf. vergrößert werden. Eine Verringerung ist nicht möglich und wird von der Zertifizierungsstelle abgelehnt werden. Wenn der Private Key exportierbar sein soll, dann wird das Zertifikat automatisch in eine PFX-Datei exportiert. Diese benötigt für den Schutz ein Passwort. Dieses muss 2x angegeben werden.
Wenn alle Werte angegeben wurden, dann wird der Schalter „issue Certificate“ freigeschaltet:
Der Prozess der Ausstellung des Zertifikates kann einige Sekunden in Anspruch nehmen. Folgende Aktionen werden ausgeführt:
- Das Script wird für den Request im Unterverzeichnis Certificates ein Arbeitsverzeichnis erstellen.
- Dann werden die Felder der GUI ausgelesen und es wird eine ini-Datei für den Request erstellt.
- Die ini-Datei wird an certreq.exe übergeben. Diese Anwendung erstellt daraus einen Certificate Signing Request. Dabei werden die asymmetrischen Schlüssel (Private Key und Public Key) erzeugt, der Private Key wird extrahiert, mit den Zusatzinformationen der ini-Datei versehen und codiert in einer CSR-Datei gespeichert.
- Danach wird certreq.exe verwendet, um den CSR an die angegebene Zertifizierungsstelle zu übergeben.
- Wenn Schritt 4 erfolgreich war, wird certreq.exe verwendet, um den Signing Response von der Zertifizierungsstelle abzuholen. Der Response ist der Public Key mit den Antragstellerinformationen zusammen. Beides ist wiederum digital von der CA signiert. Bei diesem Schritt wird der digital signierte Public Key wieder mit dem Private Key auf dem Computer vereinigt. Jetzt hat der aktuelle Computer das Zertifikat in seinem lokalen Speicher gebrauchsfertig. Wenn die Option KeyExportable nicht gewählt wurde, dann geht es im Schritt 8 weiter.
- Ansonsten wird das Zertifikat aus dem lokalen Computer in eine PFX-Datei im Arbeitsverzeichnis gespeichert. Dabei wird das eingegebene Passwort verwendet.
- Anschließend wird geprüft, ob auf dem Computer openssl.exe installiert wurde und ob in der ini-Datei die Konvertierung in eine PEM und eine KEY-Datei gewählt wurde. Ist das der Fall, dann wird openssl.exe einmal für die Extrahierung des Public Keys aus der PFX verwendet. Dabei wird eine PEM-Datei erstellt. In einem weiteren Lauf wird der Private Key aus der PFX extrahiert. Dabei wird das Passwort zum Auslesen aus der PFX und für die Encryption der KEY-Datei verwendet.
- Die Dateien im Arbeitsverzeichnis werden in einem ZIP-Archiv komprimiert. Die ZIP-Datei wird im Unterverzeichnis Certificates erstellt und beinhaltet das Datum und die Uhrzeit im ISO-Format sowie den CommonName.
- Das Arbeitsverzeichnis wird gelöscht.
Der Benutzer kann den Prozess in der Statuszeile verfolgen. Danach wird das Ergebnis angezeigt:
Anschließend wird die ZIP-Datei im Windows Explorer automatisch geöffnet. Hier befinden sich die vorher aufgezählten Dateien. In meinem Beispiel war keine Konvertierung in eine PEM- und eine KEY-Datei möglich, weil ich noch kein openssl.exe installiert hatte:
Aber die CER-Datei mit dem Public Key entspricht meinen Erwartungen. Hier sieht man auch noch einmal, wie die Werte der Eingabe bzw. der ini-Datei angezeigt werden:
Und auch die beiden SAN-Einträge (einer ist ja automatisch gleich dem CommonName erstellt worden) sind dabei:
Ausstellung eines Zertifikates mit openssl.exe
Mit openssl.exe wird die Funktionalität noch einmal erweitert. Ich habe mir die erforderlichen Dateien unter c:\Program Files in einem Verzeichnis abgelegt:
Danach kontrolliere ich noch einmal den in der ini-Datei hinterlegten Pfad. Hier sind keine Leerzeichen erlaubt:
So ausgestattet starte ich einen neuen Request mit meinem Script:
Der Prozess läuft fehlerfrei und schnell durch. Nach dem Abschluss wird der Inhalt der Zip-Datei angezeigt. Hier finde ich die PEM-Datei mit dem Public Key und die KEY-Datei mit dem PrivateKey:
Beide sind BASE64-kodiert und lassen sich mit Notepad anzeigen:
Der Private Key in der KEY-Datei wurde mit dem angegebenen Passwort verschlüsselt:
Ausstellung eines Zertifikates mit einem CSR
Manchmal müssen wir das Schlüsselpaar nicht selber erzeugen. Dann wird das vom Zielgerät oder dem Zielservice vorgenommen. In diesem Fall erhalten wir einen Certificate Signing Request (CSR), der alle Angaben zum Verwender inklusive dem Public Key enthält. Solche Dateien sind BASE64-kodiert und lassen sich mit Notepad öffnen:
Mein Script hat für den Import 2 Schalter. In diesem Modus werden alle Felder ausgeblendet, die jetzt nicht benötigt werden. Üblicherweise kennen Drittsysteme unsere Zertifikatvorlagen nicht. Daher muss die Vorlage noch ausgewählt werden. Danach kann dann entweder der BASE64-Text reinkopiert werden oder man ließt ihn über einen OpenDialog aus einer Datei ein:
Danach kann der Ausstellungsvorgang gestartet werden:
Das Ergebnis kommt recht schnell:
Wenn ein openssl installiert ist, dann wird auch wieder eine PEM-Datei erstellt. Die PFX-Datei und die KEY-Datei fehlen, denn diese haben wir nicht mit dem CSR erhalten. Aber die Public Key Dateien können wieder zum Requester zurück übertragen werden:
Download
Hier könnt ihr euch das Script in der aktuellsten Version auf meinem Gitlab-Server herunterladen: https://gitlab.ws-its.de/stephan/ps-certificaterequesttool