Werbung hier klicken! www.conrad.de Werbung

Mini-Howto zur Zertifikat-Erstellung

Inhalt:

  1. Vorwort
  2. Das CA-Zertifikat erstellen
  3. Ein Server-Zertifikat erstellen
  4. Ein Client-Zertifikat (E-Mail) erstellen
  5. Die Zertifikat-Datenbank
  6. Die Certificate Revocation List (CRL) erstellen
  7. Ein Zertifikat widerrufen

0. Vorwort

Dieses Mini-Howto soll die schrittweise Erstellung von X.509-Zertifikaten beschreiben, wie man sie zum Beispiel für den Betrieb eines Webservers mit SSL oder für die Signierung/Verschlüsselung im E-Mail-Programm benötigt. Den Schwerpunkt soll hierbei die Erstellung dieser Zertifikate mit openssl bilden, nicht die Installation oder Verwendung der Zertifikate in apache, Outlook Express oder ähnlichen Programmen. Auch soll nicht so sehr in die Tiefe gegangen werden, wer sich dafür interessiert sei auf die Literatur im Netz verwiesen (Google is your friend :-).

Das Erstellen eines Zertifikats lässt sich grob in drei Schritte gliedern. Zunächst muss ein Schlüsselpaar, das heißt ein privater und ein öffentlicher Schlüssel, erstellt werden. Der öffentliche Schlüssel wird anschließend zusammen mit anderen Informationen (Namen und anderen Parametern des Schlüsselinhabers) als so genannter Certificate Signing Request (CSR) an die Certificate Authority (= Zertifizierungsinstanz, kurz: CA) geschickt. Aufgabe dieser CA ist es, durch geeignete Maßnahmen die Richtigkeit dieser Angaben zu überprüfen und den CSR mit der Signatur der CA zu bestätigen, sozusagen zu beglaubigen, und als fertiges Zertifikat zurück zum so genannten Antragsteller zu schicken.

Inzwischen gibt es schon einige Firmen, bei denen man sich ein Zertifikat für den E-Mail-Verkehr und/oder für einen SSL-Server besorgen kann, allerdings muss man diese Dienstleistung bezahlen. Der Vorteil solcher Zertifikate ist allerdings, dass viele Browser die Stammzertifikate dieser CAs schon kennen und ihnen damit automatisch vertrauen; bei selbsterstellten ist das natürlich nicht der Fall. Hier muss man durch die nachträgliche Installation des CA-Stammzertifikats im Browser selbst dafür sorgen.

1. Das CA-Zertifikat erstellen

Als erstes muss für die CA selbst ein Schlüsselpaar erzeugt werden. Dazu verwendet man folgenden Befehl:

openssl genrsa -out ca.key 1024

Das Schlüsselpaar landet dabei in der Datei "ca.key" und ist -da wir entsprechende Kommandozeilenparameter weggelassen haben- _unverschlüsselt_! Sicherer wäre es natürlich, wenn man das Schlüsselpaar verschlüsselt speichert. Sollen die zu erstellenden Zertifikate in einer Produktionsumgebung zum Einsatz kommen, so wäre dies eindeutig die empfohlene Variante. Dazu wird der obige Befehl abgeändert zu:

openssl genrsa -des3 -out ca.key 1024

Hierbei wird man zur Eingabe eines Passwortes aufgefordert, mit welchem das Schlüsselpaar verschlüsselt abgespeichert wird.

Jetzt stellt man den Certificate Signing Request zusammen. Um nicht an die systemweit gültige openssl.conf gebunden zu sein, verwenden wir hier und auch später eigene Konfigurationsdateien. Wer möchte, kann natürlich auch die openssl.conf an seine Bedürfnisse anpassen und dann diese verwenden. Hier also die eigene Konfigurationsdatei:

ca.config:
[ req ]
default_bits       = 1024
distinguished_name = req_DN
string_mask        = nombstr

[ req_DN ]
countryName                     = "1. Country Name             (2 letter code)"
countryName_default             = DE
countryName_min                 = 2
countryName_max                 = 2
stateOrProvinceName             = "2. State or Province Name   (full name)    "
#stateOrProvinceName_default     =
localityName                    = "3. Locality Name            (eg, city)     "
localityName_default            = Chemnitz
0.organizationName              = "4. Organization Name        (eg, company)  "
0.organizationName_default      = Mustermann
organizationalUnitName          = "5. Organizational Unit Name (eg, section)  "
organizationalUnitName_default  = Certificate Authority
commonName                      = "6. Common Name              (eg, CA name)  "
commonName_max                  = 64
commonName_default              = Mustermann CA
emailAddress                    = "7. Email Address            (eg, name@FQDN)"
emailAddress_max                = 40
emailAddress_default            = ca@mustermann.de

Mit folgendem Befehl wird nun der CSR erstellt:

openssl req -config ca.config -new -key ca.key -out ca.csr

Falls man das erstellte Schlüsselpaar mit einem Passwort geschützt hat, wird dieses zunächst abgefragt, damit auf den Schlüssel zugegriffen werden kann. Anschließend wird man zur Eingabe der CSR-Daten aufgefordert, hatte man die Konfigurationsdatei schon an seine Verhältnisse angepasst, braucht man alle Angaben nur noch bestätigen.

Das endgültige Zertifikat enthält noch ein paar Erweiterungen. Diese legen wir in der Datei ca.ext fest.

ca.ext:
extensions = x509v3

[ x509v3 ]
basicConstraints      = CA:true,pathlen:0
crlDistributionPoints = URI:http://www.mustermann.de/ca/mustermann.crl
nsCertType            = sslCA,emailCA,objCA
nsCaPolicyUrl         = "http://www.mustermann.de/ca/policy.htm"
nsCaRevocationUrl     = "http://www.mustermann.de/ca/heimpold.crl"
nsComment             = "Mustermann CA"

Der Parameter nsCaRevocationUrl gibt die URL an, unter der man später die Certificate Revocation List (CRLs), also die Liste mit zurückgezogenen und für ungültig erklärten Zertifikaten, veröffentlicht.

Mit Hilfe des Parameters nsCaPolicyUrl kann man einen URL angeben, unter welchem die Richtlinien der Zertifikatsvergabe eingesehen werden können.

Das eigentliche (selbstsignierte) CA-Zertifikat erzeugen wir nun mit:

openssl x509 -days 1095 -extfile ca.ext \
             -signkey ca.key \
             -in ca.csr \
             -req \
             -out ca.crt

Zusammengefasst haben wir für die CA nun 2 wichtige Dateien: die ca.key, welche den privaten und öffentlichen Schlüssel enthält, und die ca.crt, worin der öffentliche Schlüssel der CA und ein paar weitere Angaben über diese abgelegt sind. Und eben diese Kombination, öffentlicher Schlüssel und die Informationen über den Schlüsselinhaber, bezeichnet man als Zertifikat. Handelt es sich -wie in diesem Fall- um ein Zertifikat einer CA, so spricht man auch von Root-, Wurzel- oder Stammzertifikat.

Alle ausgestellten Zertifikate, auch das Stammzertifikat, müssen in die so genannte Zertifikat-Datenbank aufgenommen werden, doch dazu siehe Punkt 4.

2. Ein Server-Zertifikat erstellen

Die Vorgehensweise zum Erstellen eines Server-Zertifikats sind nicht wesentlich anders. Man benötigt wieder ein Schlüsselpaar:

openssl genrsa -out server.key 1024

Idealerweise speichert man auch dieses Schlüsselpaar nur verschlüsselt ab, indem man -wie oben beim CA-Schlüsselpaar- noch den Parameter -des3 ergänzt. Der private Schlüssel wird später vom Webserver verwendet, um Client-Verbindungen zu verschlüsseln, das heißt, der Server muss das Passwort kennen, um an den Schlüssel zu kommen. Üblicherweise wird dann beim beim jedem Starten des Webservers dieses Passwort abgefragt, was man nur verhindern kann, wenn man das Schlüsselpaar unverschlüsselt abspeichert. Man entscheide selbst, welche Sicherheit man benötigt.

Im nächsten Schritt erstellen wir das Zertifikat, das von unserer oben erzeugten CA signiert ist. Um den CSR zu erstellen, verwenden wir wieder eine Konfigurations- und eine Erweiterungsdatei:

server.config:
[ req ]
default_bits       = 1024
distinguished_name = req_DN
string_mask        = nombstr

[ req_DN ]
countryName                     = "1. Country Name             (2 letter code)"
countryName_default             = DE
countryName_min                 = 2
countryName_max                 = 2
stateOrProvinceName             = "2. State or Province Name   (full name)    "
#stateOrProvinceName_default     =
localityName                    = "3. Locality Name            (eg, city)     "
localityName_default            = Chemnitz
0.organizationName              = "4. Organization Name        (eg, company)  "
0.organizationName_default      = Mustermann
organizationalUnitName          = "5. Organizational Unit Name (eg, section)  "
organizationalUnitName_default  = Server
commonName                      = "6. Common Name              (eg, CA name)  "
commonName_max                  = 64
commonName_default              = www.mustermann.de
emailAddress                    = "7. Email Address            (eg, name@FQDN)"
emailAddress_max                = 40
emailAddress_default            = webmaster@mustermann.de
server.ext
extensions = x509v3

[ x509v3 ]
nsCertType       = server
keyUsage         = digitalSignature,nonRepudiation,keyEncipherment
extendedKeyUsage = msSGC,nsSGC,serverAuth

Um den CSR und danach das eigentliche Zertifikat zu erzeugen, verwendet man die zwei folgenden openssl-Kommandos. Beim zweiten Befehl fällt der Parameter CAserial auf: jedes von der CA ausgestellte Zertifikate erhält eine Seriennummer. Normalerweise hat das erste von der CA ausgestellte Zertifikat (das CA-eigene CA-Zertifikat) die Nummer 0. Deshalb haben wir oben den Parameter weggelassen. Da das folgende Zertifkat und alle weiteren fortlaufend nummeriert werden sollen, erstellen wir zunächst eine Datei, in welcher die laufende Seriennummer geführt wird:

echo -ne '01' > ca.serial

Wie erwähnt, dieser Schritt ist nur vor dem ersten Zertifikat (eigentlich dem zweiten, wenn man das Stammzertifikat mitrechnet) nötig, openssl verwaltet die Datei anschließend selbst. Nun die eigentlichen zwei openssl-Kommandos:

openssl req -config server.config -new -key server.key -out server.csr
openssl x509 -days 730 -extfile server.ext \
             -CA ca.crt -CAkey ca.key -CAserial ca.serial \
             -in server.csr -req \
             -out server.crt

Und fertig ist das Server-Zertifikat. Es muss nur noch in die Zertifikat-Datenbank eingefügt werden (siehe Punkt 4).

3. Ein Client-Zertifikat (E-Mail) erstellen

Die bereits bekannte Reihenfolge: Schlüssel, CSR, Zertifikat. Dazu wieder eine andere Konfigurations- und eine andere Erweiterungsdatei:

user.config

[ req ]
default_bits       = 1024
distinguished_name = req_DN
string_mask        = nombstr

[ req_DN ]
countryName                     = "1. Country Name             (2 letter code)"
countryName_default             = DE
countryName_min                 = 2
countryName_max                 = 2
stateOrProvinceName             = "2. State or Province Name   (full name)    "
#stateOrProvinceName_default     =
localityName                    = "3. Locality Name            (eg, city)     "
localityName_default            = Chemnitz
0.organizationName              = "4. Organization Name        (eg, company)  "
0.organizationName_default      = Mustermann
organizationalUnitName          = "5. Organizational Unit Name (eg, section)  "
#organizationalUnitName_default  =
commonName                      = "6. Common Name              (eg, CA name)  "
commonName_max                  = 64
commonName_default              = Max Mustermann
emailAddress                    = "7. Email Address            (eg, name@FQDN)"
emailAddress_max                = 40
emailAddress_default            = max@mustermann.de

user.ext

extensions = x509v3

[ x509v3 ]
nsCertType = client,email,objsign
keyUsage   = digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment

Die folgenden Befehle sollten jetzt schon bekannt vorkommen. Auch hier ist es wieder möglich, den erstellten privaten Schlüssel mit einem Passwort zu schützen. Der zusätzliche, letzte Befehl ist neu und fordert auch zur Eingabe eines Passwortes auf. Mit diesem Befehl wird das Zertifikat und der private Schlüssel in eine Datei gepackt, welche von allen gängigen E-Mail-Programmen importiert werden kann. Da diese Datei den privaten Schlüssel enthält, sollte sie mit einem Passwort verschlüsselt sein. Dieses Passwort benötigt man dann auch, um die Datei "myname.p12" im E-Mail-Programm zu importieren. Nur nebenbei: das Importieren macht man unter Windows am besten mit dem Zertifikatmanager, zu finden über Systemsteuerung | Internet-Optionen | Inhalt | Zertifikate. Danach kann man das Zertifikat einem Konto/Kontakt in Outlook [Express] zuordnen.

openssl genrsa -out myname.key 1024

openssl req -config user.config -new -key myname.key -out myname.csr

openssl x509 -days 730 -extfile user.ext \
             -CA ca.crt -CAkey ca.key -CAserial ca.serial \
             -in myname.csr -req \
             -out myname.crt

openssl pkcs12 -export -in myname.crt -inkey myname.key -out myname.p12

Das Zertifikat muss noch zur Zertifikat-Datenbank hinzugefügt werden, dazu jetzt mehr.

4. Die Zertifikat-Datenbank

Über die von der CA ausgestellten Zertifikate wird eine Datenbank geführt. Üblicherweise heißt diese Datei index.txt, welche eine einfache Textdatei ist. Sie enthält 6 Spalten, welche durch Tabulatoren getrennt sind. Die erste Spalte enthält den Status des Eintrags, entweder "V" für valid, "E" für expired oder "R" für revoked. In der zweiten Spalte folgt das Ablaufdatum des Zertifikats, in der Form YYMMDDHHmmss und einem angehängtem "Z" (das "Z" steht für Zulu, also Greenwich Mean Time). Die nächste Spalte ist für gültige Zertifikate leer, bei zurückgerufenen Zertifikaten enthält sie das Rückrufdatum in der gleichen Syntax wie das vorangegangene Datum. Die vierte Spalte enthält die Seriennummer, die fünfte den Speicherplatz der Zertifikates, der zur Zeit immer mit "unknown" ausgefüllt wird. Die letzte Spalte enthält den "distinguished name" des Zertifikates.

Beispiel einer index.txt (die letzte Spalte ist gekürzt):

V       040229094920Z                   00      unknown /C=DE...
V       030301094939Z                   01      unknown /C=DE...
R       030301094954Z  020101000000Z    02      unknown /C=DE...
V       030301095026Z                   03      unknown /C=DE...

Sobald ein Zertifikat von der CA ausgestellt wurde, sollte ein entsprechender Eintrag in diese Datenbank eingefügt werden (auch für das Stammzertifikat). Die von oben bereits bekannten openssl-Kommandos machen dies nicht selbst, man muss das von Hand erledigen oder verwendet dieses kleine Perl-Script:

update-index.pl

#!/usr/bin/perl

$openssl = '/usr/bin/openssl';
$crt_filename = $ARGV[0];
$index_filename = "index.txt";

open(OPENSSL, "$openssl x509 -noout -serial -subject -enddate -in $crt_filename |") ||
  die "Can't open $openssl: $!";

while(<OPENSSL>) {
  chomp;
  ($key, $value) = split(/\s*=\s*/, $_, 2);
  $key = uc($key);
  if ($key eq "NOTAFTER") {
    ($mon,$day,$time,$year,$stuff) = split(/ +/, $value, 5);
    $time =~ s/://g;
    %Months = ( 'Jan' => '01', 'Feb' => '02', 'Mar' => '03', 'Apr' => '04',
                'May' => '05', 'Jun' => '06', 'Jul' => '07', 'Aug' => '08',
                'Sep' => '09', 'Oct' => '09', 'Nov' => '11', 'Dec' => '12' );
    $value = sprintf(qq[%s%02d%02d${time}Z], substr($year,2,2), $Months{$mon}, $day);
  }
  #printf(qq[%s="%s"\n], $key, $value);
  $$key = $value;
}
close(OPENSSL);

print "Updating $index_filename...";

open(DB, ">> $index_filename") || die "Can't open $index_filename: $!";
print DB "V\t$NOTAFTER\t\t$SERIAL\tunknown\t$SUBJECT\n";
close(DB);

print "done.\n";

Das Script erwartet als ersten Parameter den Dateinamen des Zertifikats, welches in die Datenbank aufgenommen werden soll.

5. Die Certificate Revocation List (CRL) erstellen

Zu jeder CA gehört noch eine CRL. Diese Liste enthält Angaben über die Zertifikate, die für ungültig erklärt und damit zurückgezogen wurden. Auch hierfür wird wieder eine Konfigurationsdatei benötigt.

crl.config

[ ca ]
default_ca       = CA_default                   # the default ca section

[ CA_default ]
dir              = ./                           # where everything is kept
database         = $dir/index.txt               # database index file.
certificate      = $dir/public/heimpold-ca.crt  # the CA certificate
crl              = $dir/public/heimpold-ca.crl  # the current CRL
private_key      = $dir/private/heimpold-ca.key # the private key
default_crl_days = 183                          # how long before next CRL

Die CRL wird nun erstellt mit:

openssl ca -config crl.config -gencrl -out ca.crl

Die Angaben über ungültige Zertifikate entnimmt der Befehl natürlich der Zertifikat-Datenbank, daher sollte die CRL immer neu erstellt werden, wenn sich Einträge in der Datenbank verändert haben.

6. Ein Zertifikat widerrufen

Um ein Zertifikat zu widerrufen muss logischerweise der Eintrag in der Datenbank geändert werden, und anschließend die CRL neu erstellt werden. Das Ändern der Einträge erfolgt mit folgenden Befehl:

openssl ca -config crl.config -revoke name.crt

Der Befehl aktualisiert die Datenbank selbst. Die neue CRL erstellt man dann wie oben beschrieben.


© 2001 - 2004 Michael Heimpold, letzte Aktualisierung: 2004-01-28