Wie unterschreiben Sie eine Zertifikatsignierungsanforderung bei Ihrer Zertifizierungsstelle?

195

Während meiner Suche habe ich verschiedene Möglichkeiten zum Signieren einer SSL-Zertifikatsignierungsanforderung gefunden:

  1. Verwenden des x509Moduls:

    openssl x509 -req -days 360 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
    
  2. Verwenden des caModuls:

    openssl ca -cert ca.crt -keyfile ca.key -in server.csr -out server.crt
    

Hinweis: Ich bin mir nicht sicher, ob die richtigen Parameter für diesen verwendet werden. Bitte geben Sie die korrekte Verwendung an, wenn ich sie verwenden soll.

Wie sollte man Zertifikatsanforderungen bei Ihrer Zertifizierungsstelle signieren? Ist eine Methode besser als die andere (zum Beispiel eine, die veraltet ist)?

Bernard Rosset
quelle
1
Ich mag dieses kleine Skript, das eine Zertifizierungsstelle einrichtet und es Ihnen ermöglicht, signierte "untergeordnete" Zertifikate zu generieren. Hinweis: Wenn Sie möchten, dass Ihr System über die Zertifikate zufrieden ist (wie bei S / MIME oder so weiter), müssen Sie das CA-Zertifikat als "vertrauenswürdiges Stammverzeichnis" hinzufügen.
Glas
Soweit ich sehen kann, cahandelt es sich um Fälle, in denen Sie es ernst meinen, CA zu werden.
X-Yuri
Vielleicht finden Sie meine Antwort interessant.
X-Yuri
Stack Overflow ist eine Site für Programmier- und Entwicklungsfragen. Diese Frage scheint nicht zum Thema zu gehören, da es nicht um Programmierung oder Entwicklung geht. Weitere Informationen zu diesen Themen finden Sie hier in der Hilfe. Vielleicht ist Super User oder Unix & Linux Stack Exchange ein besserer Ort, um zu fragen.
Jww

Antworten:

458
1. Using the x509 module
openssl x509 ...
...

2 Using the ca module
openssl ca ...
...

Ihnen fehlt der Auftakt zu diesen Befehlen.

Dies ist ein zweistufiger Prozess. Zuerst richten Sie Ihre Zertifizierungsstelle ein und dann signieren Sie ein Endentitätszertifikat (auch bekannt als Server oder Benutzer). Beide Befehle teilen die beiden Schritte in einen. Beide setzen voraus, dass bereits eine OpenSSL-Konfigurationsdatei für Zertifizierungsstellen und Serverzertifikate (Endentität) eingerichtet ist.


Erstellen Sie zunächst eine grundlegende Konfigurationsdatei :

$ touch openssl-ca.cnf

Fügen Sie dann Folgendes hinzu:

HOME            = .
RANDFILE        = $ENV::HOME/.rnd

####################################################################
[ ca ]
default_ca    = CA_default      # The default ca section

[ CA_default ]

default_days     = 1000         # How long to certify for
default_crl_days = 30           # How long before next CRL
default_md       = sha256       # Use public key default MD
preserve         = no           # Keep passed DN ordering

x509_extensions = ca_extensions # The extensions to add to the cert

email_in_dn     = no            # Don't concat the email in the DN
copy_extensions = copy          # Required to copy SANs from CSR to cert

####################################################################
[ req ]
default_bits       = 4096
default_keyfile    = cakey.pem
distinguished_name = ca_distinguished_name
x509_extensions    = ca_extensions
string_mask        = utf8only

####################################################################
[ ca_distinguished_name ]
countryName         = Country Name (2 letter code)
countryName_default = US

stateOrProvinceName         = State or Province Name (full name)
stateOrProvinceName_default = Maryland

localityName                = Locality Name (eg, city)
localityName_default        = Baltimore

organizationName            = Organization Name (eg, company)
organizationName_default    = Test CA, Limited

organizationalUnitName         = Organizational Unit (eg, division)
organizationalUnitName_default = Server Research Department

commonName         = Common Name (e.g. server FQDN or YOUR name)
commonName_default = Test CA

emailAddress         = Email Address
emailAddress_default = [email protected]

####################################################################
[ ca_extensions ]

subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid:always, issuer
basicConstraints       = critical, CA:true
keyUsage               = keyCertSign, cRLSign

Die obigen Felder stammen aus einem komplexeren Feld openssl.cnf(Sie finden es in /usr/lib/openssl.cnf), aber ich denke, sie sind die Grundvoraussetzungen für die Erstellung des CA-Zertifikats und des privaten Schlüssels.

Passen Sie die Felder oben an Ihren Geschmack an. Die Standardeinstellungen ersparen Ihnen die Zeit, dieselben Informationen einzugeben, während Sie mit Konfigurationsdateien und Befehlsoptionen experimentieren.

Ich habe die CRL-relevanten Dinge weggelassen, aber Ihre CA-Operationen sollten sie haben. Siehe openssl.cnfund den zugehörigen crl_extAbschnitt.

Führen Sie dann Folgendes aus. Das -nodeslässt das Passwort oder die Passphrase weg, damit Sie das Zertifikat überprüfen können. Es ist eine wirklich schlechte Idee, das Passwort oder die Passphrase wegzulassen.

$ openssl req -x509 -config openssl-ca.cnf -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM

Nachdem der Befehl ausgeführt wurde, cacert.pemist dies Ihr Zertifikat für CA-Vorgänge und cakey.pemder private Schlüssel. Der private Schlüssel hat kein Passwort oder keine Passphrase.

Sie können das Zertifikat wie folgt sichern.

$ openssl x509 -in cacert.pem -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 11485830970703032316 (0x9f65de69ceef2ffc)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, ST=MD, L=Baltimore, CN=Test CA/[email protected]
        Validity
            Not Before: Jan 24 14:24:11 2014 GMT
            Not After : Feb 23 14:24:11 2014 GMT
        Subject: C=US, ST=MD, L=Baltimore, CN=Test CA/[email protected]
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                    00:b1:7f:29:be:78:02:b8:56:54:2d:2c:ec:ff:6d:
                    ...
                    39:f9:1e:52:cb:8e:bf:8b:9e:a6:93:e1:22:09:8b:
                    59:05:9f
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                4A:9A:F3:10:9E:D7:CF:54:79:DE:46:75:7A:B0:D0:C1:0F:CF:C1:8A
            X509v3 Authority Key Identifier:
                keyid:4A:9A:F3:10:9E:D7:CF:54:79:DE:46:75:7A:B0:D0:C1:0F:CF:C1:8A

            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage:
                Certificate Sign, CRL Sign
    Signature Algorithm: sha256WithRSAEncryption
         4a:6f:1f:ac:fd:fb:1e:a4:6d:08:eb:f5:af:f6:1e:48:a5:c7:
         ...
         cd:c6:ac:30:f9:15:83:41:c1:d1:20:fa:85:e7:4f:35:8f:b5:
         38:ff:fd:55:68:2c:3e:37

Testen Sie den Zweck folgendermaßen (machen Sie sich keine Sorgen über Any Purpose: Yes; siehe "kritisch, CA: FALSE", aber "CA für alle Zwecke: Ja" ).

$ openssl x509 -purpose -in cacert.pem -inform PEM
Certificate purposes:
SSL client : No
SSL client CA : Yes
SSL server : No
SSL server CA : Yes
Netscape SSL server : No
Netscape SSL server CA : Yes
S/MIME signing : No
S/MIME signing CA : Yes
S/MIME encryption : No
S/MIME encryption CA : Yes
CRL signing : Yes
CRL signing CA : Yes
Any Purpose : Yes
Any Purpose CA : Yes
OCSP helper : Yes
OCSP helper CA : Yes
Time Stamp signing : No
Time Stamp signing CA : Yes
-----BEGIN CERTIFICATE-----
MIIFpTCCA42gAwIBAgIJAJ9l3mnO7y/8MA0GCSqGSIb3DQEBCwUAMGExCzAJBgNV
...
aQUtFrV4hpmJUaQZ7ySr/RjCb4KYkQpTkOtKJOU1Ic3GrDD5FYNBwdEg+oXnTzWP
tTj//VVoLD43
-----END CERTIFICATE-----

Für Teil zwei werde ich eine weitere Konfigurationsdatei erstellen, die leicht verdaulich ist. Erstens touchdie openssl-server.cnf(Sie können eine davon auch für Benutzerzertifikate erstellen).

$ touch openssl-server.cnf

Öffnen Sie es dann und fügen Sie Folgendes hinzu.

HOME            = .
RANDFILE        = $ENV::HOME/.rnd

####################################################################
[ req ]
default_bits       = 2048
default_keyfile    = serverkey.pem
distinguished_name = server_distinguished_name
req_extensions     = server_req_extensions
string_mask        = utf8only

####################################################################
[ server_distinguished_name ]
countryName         = Country Name (2 letter code)
countryName_default = US

stateOrProvinceName         = State or Province Name (full name)
stateOrProvinceName_default = MD

localityName         = Locality Name (eg, city)
localityName_default = Baltimore

organizationName            = Organization Name (eg, company)
organizationName_default    = Test Server, Limited

commonName           = Common Name (e.g. server FQDN or YOUR name)
commonName_default   = Test Server

emailAddress         = Email Address
emailAddress_default = [email protected]

####################################################################
[ server_req_extensions ]

subjectKeyIdentifier = hash
basicConstraints     = CA:FALSE
keyUsage             = digitalSignature, keyEncipherment
subjectAltName       = @alternate_names
nsComment            = "OpenSSL Generated Certificate"

####################################################################
[ alternate_names ]

DNS.1  = example.com
DNS.2  = www.example.com
DNS.3  = mail.example.com
DNS.4  = ftp.example.com

Wenn Sie Ihre Workstation entwickeln und als Server verwenden müssen, müssen Sie möglicherweise Folgendes für Chrome tun. Andernfalls kann sich Chrome beschweren, dass ein allgemeiner Name ungültig ist ( ERR_CERT_COMMON_NAME_INVALID) . Ich bin mir nicht sicher, wie die Beziehung zwischen einer IP-Adresse im SAN und einem CN in diesem Fall ist.

# IPv4 localhost
IP.1     = 127.0.0.1

# IPv6 localhost
IP.2     = ::1

Erstellen Sie dann die Serverzertifikatsanforderung. Achten Sie darauf, * wegzulassen -x509 . Durch Hinzufügen -x509wird ein Zertifikat erstellt und keine Anforderung.

$ openssl req -config openssl-server.cnf -newkey rsa:2048 -sha256 -nodes -out servercert.csr -outform PEM

Nachdem dieser Befehl ausgeführt wurde, haben Sie eine Anforderung servercert.csrund einen privaten Schlüssel serverkey.pem.

Und Sie können es erneut überprüfen.

$ openssl req -text -noout -verify -in servercert.csr
Certificate:
    verify OK
    Certificate Request:
        Version: 0 (0x0)
        Subject: C=US, ST=MD, L=Baltimore, CN=Test Server/[email protected]
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:ce:3d:58:7f:a0:59:92:aa:7c:a0:82:dc:c9:6d:
                    ...
                    f9:5e:0c:ba:84:eb:27:0d:d9:e7:22:5d:fe:e5:51:
                    86:e1
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Subject Key Identifier:
                1F:09:EF:79:9A:73:36:C1:80:52:60:2D:03:53:C7:B6:BD:63:3B:61
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Key Encipherment
            X509v3 Subject Alternative Name:
                DNS:example.com, DNS:www.example.com, DNS:mail.example.com, DNS:ftp.example.com
            Netscape Comment:
                OpenSSL Generated Certificate
    Signature Algorithm: sha256WithRSAEncryption
         6d:e8:d3:85:b3:88:d4:1a:80:9e:67:0d:37:46:db:4d:9a:81:
         ...
         76:6a:22:0a:41:45:1f:e2:d6:e4:8f:a1:ca:de:e5:69:98:88:
         a9:63:d0:a7

Als nächstes müssen Sie es mit Ihrer CA unterschreiben.


Sie sind fast bereit, das Serverzertifikat von Ihrer Zertifizierungsstelle zu signieren. Die Zertifizierungsstellen openssl-ca.cnfbenötigen zwei weitere Abschnitte, bevor der Befehl ausgegeben wird.

Öffnen openssl-ca.cnfSie zunächst die folgenden beiden Abschnitte und fügen Sie sie hinzu.

####################################################################
[ signing_policy ]
countryName            = optional
stateOrProvinceName    = optional
localityName           = optional
organizationName       = optional
organizationalUnitName = optional
commonName             = supplied
emailAddress           = optional

####################################################################
[ signing_req ]
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer
basicConstraints       = CA:FALSE
keyUsage               = digitalSignature, keyEncipherment

Zweitens fügen Sie dem [ CA_default ]Abschnitt von Folgendes hinzu openssl-ca.cnf. Ich habe sie früher weggelassen, weil sie die Dinge komplizieren können (sie waren zu der Zeit unbenutzt). Jetzt werden Sie sehen, wie sie verwendet werden, und hoffentlich machen sie Sinn.

base_dir      = .
certificate   = $base_dir/cacert.pem   # The CA certifcate
private_key   = $base_dir/cakey.pem    # The CA private key
new_certs_dir = $base_dir              # Location for new certs after signing
database      = $base_dir/index.txt    # Database index file
serial        = $base_dir/serial.txt   # The current serial number

unique_subject = no  # Set to 'no' to allow creation of
                     # several certificates with same subject.

Drittens berühren index.txtund serial.txt:

$ touch index.txt
$ echo '01' > serial.txt

Führen Sie dann Folgendes aus:

$ openssl ca -config openssl-ca.cnf -policy signing_policy -extensions signing_req -out servercert.pem -infiles servercert.csr

Sie sollten Folgendes ähnlich sehen:

Using configuration from openssl-ca.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'US'
stateOrProvinceName   :ASN.1 12:'MD'
localityName          :ASN.1 12:'Baltimore'
commonName            :ASN.1 12:'Test CA'
emailAddress          :IA5STRING:'[email protected]'
Certificate is to be certified until Oct 20 16:12:39 2016 GMT (1000 days)
Sign the certificate? [y/n]:Y

1 out of 1 certificate requests certified, commit? [y/n]Y
Write out database with 1 new entries
Data Base Updated

Nachdem der Befehl ausgeführt wurde, haben Sie ein frisch geprägtes Serverzertifikat in servercert.pem. Der private Schlüssel wurde früher erstellt und ist in verfügbar serverkey.pem.

Schließlich können Sie Ihr frisch geprägtes Zertifikat wie folgt überprüfen:

$ openssl x509 -in servercert.pem -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 9 (0x9)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, ST=MD, L=Baltimore, CN=Test CA/[email protected]
        Validity
            Not Before: Jan 24 19:07:36 2014 GMT
            Not After : Oct 20 19:07:36 2016 GMT
        Subject: C=US, ST=MD, L=Baltimore, CN=Test Server
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:ce:3d:58:7f:a0:59:92:aa:7c:a0:82:dc:c9:6d:
                    ...
                    f9:5e:0c:ba:84:eb:27:0d:d9:e7:22:5d:fe:e5:51:
                    86:e1
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                1F:09:EF:79:9A:73:36:C1:80:52:60:2D:03:53:C7:B6:BD:63:3B:61
            X509v3 Authority Key Identifier:
                keyid:42:15:F2:CA:9C:B1:BB:F5:4C:2C:66:27:DA:6D:2E:5F:BA:0F:C5:9E

            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Key Encipherment
            X509v3 Subject Alternative Name:
                DNS:example.com, DNS:www.example.com, DNS:mail.example.com, DNS:ftp.example.com
            Netscape Comment:
                OpenSSL Generated Certificate
    Signature Algorithm: sha256WithRSAEncryption
         b1:40:f6:34:f4:38:c8:57:d4:b6:08:f7:e2:71:12:6b:0e:4a:
         ...
         45:71:06:a9:86:b6:0f:6d:8d:e1:c5:97:8d:fd:59:43:e9:3c:
         56:a5:eb:c8:7e:9f:6b:7a

Zuvor haben Sie Folgendes hinzugefügt zu CA_default: copy_extensions = copy. Diese kopiert die Erweiterung, die von der Person bereitgestellt wurde, die die Anfrage gestellt hat.

Wenn Sie dies weglassen copy_extensions = copy, fehlen Ihrem Serverzertifikat die SANs (Subject Alternate Names) wie www.example.comund mail.example.com.

Wenn Sie copy_extensions = copydie Anforderung verwenden , diese jedoch nicht überprüfen, kann der Anforderer Sie möglicherweise dazu verleiten, so etwas wie einen untergeordneten Stamm (anstelle eines Server- oder Benutzerzertifikats) zu signieren. Dies bedeutet, dass er / sie Zertifikate prägen kann, die mit Ihrer vertrauenswürdigen Wurzel verknüpft sind. Stellen Sie sicher, dass Sie die Anfrage mit überprüfen, openssl req -verifybevor Sie unterschreiben.


Wenn Sie es weglassen unique_subject oder festlegen yes, dürfen Sie nur ein Zertifikat unter dem definierten Namen des Betreffs erstellen .

unique_subject = yes            # Set to 'no' to allow creation of
                                # several ctificates with same subject.

Der Versuch, während des Experimentierens ein zweites Zertifikat zu erstellen, führt zu folgenden Ergebnissen, wenn Sie das Zertifikat Ihres Servers mit dem privaten Schlüssel der Zertifizierungsstelle signieren:

Sign the certificate? [y/n]:Y
failed to update database
TXT_DB error number 2

Ist unique_subject = noalso perfekt zum Testen.


Wenn Sie die sicherstellen wollen , den Namen der Organisation steht im Einklang zwischen selbstsignierte Zertifizierungsuntergeordnete CA und End-Entity - Zertifikate, dann fügen Sie die folgende Zeile in Ihre CA - Konfigurationsdateien:

[ policy_match ]
organizationName = match

Wenn Sie zulassen möchten, dass sich der Organisationsname ändert, verwenden Sie:

[ policy_match ]
organizationName = supplied

Es gibt andere Regeln für den Umgang mit DNS-Namen in X.509 / PKIX-Zertifikaten. In diesen Dokumenten finden Sie die Regeln:

RFC 6797 und RFC 7469 werden aufgelistet, da sie restriktiver sind als die anderen RFCs und CA / B-Dokumente. Die RFC 6797 und 7469 erlauben ebenfalls keine IP-Adresse.

jww
quelle
4
Vielen Dank für diese ausführliche Antwort ... Allerdings bin ich hier irgendwie verloren. Was ich aus dem, was Sie geschrieben haben, verstanden habe: openssl reqwird zum Generieren von CSR verwendet, openssl req -x509wird zum Generieren eines CA-Zertifikats verwendet (ich habe gesehen, dass Sie an einer anderen Stelle auch ein selbstsigniertes Zertifikat erstellen können), openssl cawird zum Signieren eines CSR mit einem CA-Zertifikat verwendet. Richtig? Was mich auch verwirrt, ist, dass die gleichen Teile der Datei openssl.cnf je nach Befehl mit unterschiedlichen Werten verwendet werden ... Ich glaube, ich bin jetzt total verloren.
Bernard Rosset
27
Zunächst openssl req -x509wird die Zertifizierungsstelle erstellt. Zweitens openssl reqwird verwendet, um die CSR des Servers zu erstellen. Drittens openssl cawird das Serverzertifikat erstellt und mit der Signatur der Zertifizierungsstelle zertifiziert.
JWW
1
"Was mich auch verwirrt ist, dass die gleichen Teile der openssl.cnf ..." - Richtig. Deshalb habe ich sie für dich in openssl-ca.cnfund ausgebrochen openssl-server.cnf. Nachdem Sie sich an sie gewöhnt haben und wie die Abschnitte aufgerufen werden, können Sie sie zu einer Monstrosität wie kombinieren openssl.cnf.
JWW
1
@ JeffPuckettII - Es ist ein allgemeiner Abschnitt. Es wird sowohl vom CA-Dienstprogramm als auch vom Req-Dienstprogramm verwendet. Sie sollten v3-Erweiterungen sein.
JWW
5
@ahnkle Verwenden Sie die Option -days für alle anderen als die standardmäßigen 30 Tage. OpenSSL docs
George
14

Zusätzlich zur Antwort von @jww möchte ich sagen, dass die Konfiguration in openssl-ca.cnf,

default_days     = 1000         # How long to certify for

Definiert die Standardanzahl der Tage, an denen das von diesem Root-Ca signierte Zertifikat gültig ist. Um die Gültigkeit von root-ca selbst festzulegen, sollten Sie die Option '-days n' verwenden in:

openssl req -x509 -days 3000 -config openssl-ca.cnf -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM

Andernfalls ist Ihr root-ca nur für den Standardmonat gültig, und jedes von dieser Stammzertifizierungsstelle signierte Zertifikat hat auch eine Gültigkeit von einem Monat.

bescheidener Wolf
quelle