Come si firma una richiesta di firma del certificato con la propria autorità di certificazione?


195

Durante la mia ricerca, ho trovato diversi modi per firmare una richiesta di firma del certificato SSL:

  1. Utilizzando il x509modulo:

    openssl x509 -req -days 360 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
    
  2. Utilizzando il camodulo:

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

Nota: non sono sicuro dell'uso dei parametri giusti per questo. Si prega di avvisare l'uso corretto se devo usarlo.

In che modo si dovrebbe usare per firmare le richieste di certificati con la propria autorità di certificazione? Un metodo è migliore dell'altro (ad esempio, uno è deprecato)?



1
Mi piace questo piccolo script che imposta una CA e ti consente di generare certificati "subordinati" firmati. Nota, se vuoi che il tuo sistema sia soddisfatto dei certificati (come per S / MIME o quant'altro), devi aggiungere il certificato CA come "radice attendibile".
vaso

Da quello che posso vedere, caè per i casi in cui sei più serio nel diventare un CA.
x-yuri,

Potresti trovare la mia risposta interessante.
x-yuri,

Stack Overflow è un sito per domande di programmazione e sviluppo. Questa domanda sembra essere fuori tema perché non si tratta di programmazione o sviluppo. Consulta quali argomenti posso chiedere qui nel Centro assistenza. Forse Super User o Unix & Linux Stack Exchange sarebbero un posto migliore da chiedere.
JWW

Risposte:


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

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

Ti manca il preludio a quei comandi.

Questo è un processo in due fasi. Prima di tutto configura la tua CA e poi firmi un certificato di entità finale (aka server o utente). Entrambi i due comandi racchiudono i due passaggi in uno. E entrambi presumono che tu abbia già un file di configurazione OpenSSL impostato sia per i certificati CA che per i server (entità finale).


Innanzitutto, crea un file di configurazione di base :

$ touch openssl-ca.cnf

Quindi, aggiungi quanto segue:

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 = test@example.com

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

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

I campi sopra sono presi da un più complesso openssl.cnf(lo puoi trovare in /usr/lib/openssl.cnf), ma penso che siano gli elementi essenziali per la creazione del certificato CA e della chiave privata.

Modifica i campi sopra per soddisfare i tuoi gusti. Le impostazioni predefinite consentono di risparmiare tempo dall'immissione delle stesse informazioni durante la sperimentazione del file di configurazione e delle opzioni di comando.

Ho omesso le cose rilevanti per CRL, ma le tue operazioni CA dovrebbero averle. Vedi openssl.cnfe relativicrl_ext sezione.

Quindi, eseguire quanto segue. Il -nodesomette la password o passphrase in modo da poter esaminare il certificato. È davvero una cattiva idea omettere la password o la passphrase.

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

Dopo l'esecuzione del comando, cacert.pemsarà il certificato per le operazioni della CA e cakey.pemsarà la chiave privata. Richiama la chiave privata non ha una password o passphrase.

È possibile scaricare il certificato con quanto segue.

$ 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/emailAddress=test@example.com
        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/emailAddress=test@example.com
        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

E testare il suo scopo con il seguente (non preoccuparti di Any Purpose: Yes; vedi "critico, CA: FALSO" ma "Qualsiasi scopo CA: Sì" ).

$ 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-----

Per la seconda parte, creerò un altro file di configurazione facilmente digeribile. Innanzitutto, touchil openssl-server.cnf(è possibile effettuare uno di questi anche per i certificati utente).

$ touch openssl-server.cnf

Quindi aprilo e aggiungi quanto segue.

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 = test@example.com

####################################################################
[ 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

Se stai sviluppando e devi utilizzare la tua workstation come server, potrebbe essere necessario eseguire le seguenti operazioni per Chrome. Altrimenti Chrome potrebbe lamentare che un nome comune non è valido ( ERR_CERT_COMMON_NAME_INVALID) . Non sono sicuro di quale sia la relazione tra un indirizzo IP nella SAN e una CN in questo caso.

# IPv4 localhost
IP.1     = 127.0.0.1

# IPv6 localhost
IP.2     = ::1

Quindi, creare la richiesta del certificato del server. Assicurati di omettere -x509 *. L'aggiunta -x509creerà un certificato e non una richiesta.

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

Dopo l'esecuzione di questo comando, avrai una richiesta servercert.csre una chiave privataserverkey.pem .

E puoi ispezionarlo di nuovo.

$ 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/emailAddress=test@example.com
        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

Successivamente, devi firmarlo con la tua CA.


Sei quasi pronto per firmare il certificato del server dalla tua CA. La CA ha openssl-ca.cnfbisogno di altre due sezioni prima di emettere il comando.

Innanzitutto, apri openssl-ca.cnfe aggiungi le seguenti due sezioni.

####################################################################
[ 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

In secondo luogo, aggiungere quanto segue alla [ CA_default ]sezione di openssl-ca.cnf. Li ho lasciati fuori prima, perché possono complicare le cose (non erano in uso al momento). Ora vedrai come vengono utilizzati, quindi speriamo che abbiano senso.

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.

Terzo, tocca index.txte serial.txt:

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

Quindi, eseguire le seguenti operazioni:

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

Dovresti vedere simile al seguente:

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:'test@example.com'
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

Dopo l'esecuzione del comando, avrai un certificato del server appena coniato servercert.pem. La chiave privata è stata creata in precedenza ed è disponibile in serverkey.pem.

Infine, puoi controllare il tuo certificato coniato di recente con quanto segue:

$ 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/emailAddress=test@example.com
        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

In precedenza, è aggiunto il testo seguente CA_default: copy_extensions = copy. Questa estensione di copia fornita dalla persona che effettua la richiesta.

Se si omette copy_extensions = copy, nel certificato del server mancheranno i nomi alternativi soggetti (SAN) come www.example.come mail.example.com.

Se si utilizza copy_extensions = copy, ma non si esamina la richiesta, il richiedente potrebbe essere in grado di indurti a firmare qualcosa come una radice subordinata (anziché un certificato server o utente). Ciò significa che sarà in grado di coniare certificati che tornano alla tua radice attendibile. Assicurati di verificare la richiesta con openssl req -verifyprima di firmare.


Se lo ometti unique_subject o lo imposti yes, ti sarà consentito creare un solo certificato con il nome distinto del soggetto.

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

Cercare di creare un secondo certificato durante la sperimentazione comporterà quanto segue quando si firma il certificato del server con la chiave privata della CA:

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

Quindi unique_subject = noè perfetto per i test.


Se si desidera assicurarsi che il nome organizzativo sia coerente tra le CA autofirmate, i certificati CA subordinati ed End-Entity , quindi aggiungere i seguenti file ai file di configurazione della CA:

[ policy_match ]
organizationName = match

Se si desidera consentire la modifica del nome dell'organizzazione , utilizzare:

[ policy_match ]
organizationName = supplied

Esistono altre regole relative alla gestione dei nomi DNS nei certificati X.509 / PKIX. Fare riferimento a questi documenti per le regole:

Sono elencati RFC 6797 e RFC 7469, poiché sono più restrittivi rispetto agli altri documenti RFC e CA / B. 6797 e 7469 di RFC non consentono neanche un indirizzo IP.


4
Grazie per la risposta esaustiva ... Tuttavia, mi sono quasi perso qui. Quello che ho capito da quello che hai scritto: openssl reqè usato per generare CSR, openssl req -x509è usato per generare certificato CA (ho visto in qualche altro posto che potresti creare anche un certificato autofirmato), openssl caè usato per firmare un CSR con un certificato CA. Destra? Ciò che mi confonde anche è che le stesse parti del file openssl.cnf vengono utilizzate con valori diversi a seconda del comando ... Penso di essere totalmente persa ora.
Bernard Rosset,

27
Innanzitutto, openssl req -x509viene utilizzato per creare la CA. In secondo luogo, openssl reqviene utilizzato per creare il CSR del server. In terzo luogo, openssl caviene utilizzato per creare il certificato del server e certificarlo con la firma della CA.
JWW

1
"Ciò che mi confonde anche è che le stesse parti di openssl.cnf ..." - Giusto. Ecco perché li ho rotto per voi in openssl-ca.cnfe openssl-server.cnf. Dopo esserti abituato e come vengono invocate le sezioni, puoi combinarle in una sorta di mostruosità openssl.cnf.
JWW

1
@JeffPuckettII - È una sezione comune. Viene utilizzato sia dall'utilità CA sia dall'utilità Req. Dovrebbero essere estensioni v3.
JWW

5
@ahnkle Usa l'opzione -days per qualcosa di diverso dai 30 giorni predefiniti. Documenti OpenSSL
george

14

Oltre alla risposta di @jww, vorrei dire che la configurazione in openssl-ca.cnf,

default_days     = 1000         # How long to certify for

definisce il numero predefinito di giorni in cui il certificato firmato da questo root-ca sarà valido. Per impostare la validità di root-ca stesso dovresti usare l'opzione '-days n' in:

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

In caso contrario, root-ca sarà valido solo per un mese predefinito e qualsiasi certificato firmato da questa CA principale avrà anche una validità di un mese.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.