web-dev-qa-db-fra.com

Comment signez-vous une demande de signature de certificat avec votre autorité de certification?

Lors de ma recherche, j'ai trouvé plusieurs façons de signer une demande de signature de certificat SSL:

  1. Utilisation du module x509:

    openssl x509 -req -days 360 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
    
  2. Utilisation du module ca:

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

Remarque: je ne suis pas sûr de l’utilisation des bons paramètres pour celui-ci. S'il vous plaît aviser l'utilisation correcte si je dois l'utiliser.

Quel moyen faut-il utiliser pour signer les demandes de certificat avec votre autorité de certification? Une méthode est-elle meilleure que l'autre (par exemple, une méthode est déconseillée)?

167
Bernard Rosset
1. Using the x509 module
openssl x509 ...
...

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

Vous manquez le prélude à ces commandes.

C'est un processus en deux étapes. Tout d'abord, vous configurez votre autorité de certification, puis vous signez un certificat d'entité finale (serveur ou utilisateur a.k.a). Les deux commandes séparent les deux étapes en une seule. Et les deux supposent que vous avez déjà un fichier de configuration OpenSSL configuré pour les certificats d'autorité de certification et de serveur (entité finale).


Tout d’abord, créez un fichier de configuration :

$ touch openssl-ca.cnf

Ensuite, ajoutez ce qui suit:

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

Les champs ci-dessus proviennent d'un plus complexe openssl.cnf (vous pouvez le trouver dans /usr/lib/openssl.cnf), mais je pense qu'ils sont essentiels à la création du certificat de l'autorité de certification et de la clé privée.

Ajustez les champs ci-dessus à votre goût. Les valeurs par défaut vous évitent de saisir les mêmes informations lorsque vous testez des options de fichier de configuration et de commande.

J'ai omis les éléments relatifs aux listes de révocation de certificats, mais vos opérations d'autorité de certification devraient en disposer. Voir openssl.cnf et la section connexe crl_ext.

Ensuite, exécutez ce qui suit. Le -nodes omet le mot de passe ou la phrase secrète afin que vous puissiez examiner le certificat. C'est une () mauvaise mauvaise idée d'omettre le mot de passe ou la phrase secrète.

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

Une fois la commande exécutée, cacert.pem sera votre certificat pour les opérations de l'autorité de certification et cakey.pem sera la clé privée. Rappelez que la clé privée n’a pas de mot de passe ou de phrase secrète.

Vous pouvez vider le certificat avec les éléments suivants.

$ 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

Et testez son objectif avec les éléments suivants (ne vous inquiétez pas du Any Purpose: Yes; voir "critical, CA: FALSE" mais "Any Purpose CA: Yes" ).

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

Pour la deuxième partie, je vais créer un autre fichier de configuration facile à digérer. Tout d'abord, touch le openssl-server.cnf (vous pouvez également en créer un pour les certificats d'utilisateur).

$ touch openssl-server.cnf

Puis ouvrez-le et ajoutez ce qui suit.

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

Si vous développez et devez utiliser votre station de travail en tant que serveur, vous devrez peut-être effectuer les opérations suivantes pour Chrome. Sinon Chrome peut se plaindre d'un nom commun non valide (ERR_CERT_COMMON_NAME_INVALID) . Je ne suis pas sûr de la relation entre une adresse IP dans le SAN et un CN dans cet exemple.

# IPv4 localhost
IP.1     = 127.0.0.1

# IPv6 localhost
IP.2     = ::1

Ensuite, créez la demande de certificat de serveur. Assurez-vous de omettre -x509 *. L'ajout de -x509 créera un certificat et non une demande.

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

Une fois cette commande exécutée, vous aurez une demande dans servercert.csr et une clé privée dans serverkey.pem.

Et vous pouvez l'inspecter à nouveau.

$ 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

Ensuite, vous devez le signer avec votre autorité de certification.


Vous êtes presque prêt à signer le certificat du serveur par votre autorité de certification. Le openssl-ca.cnf de l'autorité de certification a besoin de deux autres sections avant d'exécuter la commande.

Tout d’abord, ouvrez openssl-ca.cnf et ajoutez les deux sections suivantes.

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

Deuxièmement, ajoutez ce qui suit à la section [ CA_default ] de openssl-ca.cnf. Je les ai laissés de côté plus tôt, car ils peuvent compliquer les choses (ils n'étaient pas utilisés à l'époque). Maintenant, vous verrez comment ils sont utilisés, alors espérons qu'ils auront un sens.

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.

Troisièmement, appuyez sur index.txt et serial.txt:

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

Ensuite, procédez comme suit:

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

Vous devriez voir semblable à ce qui suit:

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

Une fois la commande exécutée, vous aurez un certificat de serveur fraîchement créé dans servercert.pem. La clé privée a été créée précédemment et est disponible dans serverkey.pem.

Enfin, vous pouvez inspecter votre certificat fraîchement frappé avec les éléments suivants:

$ 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

Auparavant, vous aviez ajouté le texte suivant à CA_default: copy_extensions = copy. Cette copie copie l'extension fournie par la personne qui fait la demande.

Si vous omettez copy_extensions = copy, votre certificat de serveur n'aura pas les noms de sujet, comme www.example.com et mail.example.com.

Si vous utilisez copy_extensions = copy, sans examiner la demande, le demandeur peut peut-être vous inciter à signer quelque chose qui ressemble à une racine subordonnée (plutôt qu'à un certificat d'utilisateur ou de serveur). Ce qui signifie qu'il/elle sera capable de monnayer les certificats qui sont reliés à votre racine de confiance. Assurez-vous de vérifier la demande avec openssl req -verify avant de signer.


Si vous omettez unique_subject ou le définissez sur yes, vous ne pourrez créer que un certificat sous le nom distinctif du sujet.

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

Si vous essayez de créer un deuxième certificat pendant les essais, vous obtiendrez ce qui suit lors de la signature du certificat de votre serveur avec la clé privée de l'autorité de certification:

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

Donc, unique_subject = no est parfait pour les tests.


Si vous voulez vous assurer que le nom de l'organisation est cohérent entre les autorités de certification auto-signées, l'autorité de certification secondaire et Certificats d’entité finale , puis ajoutez les éléments suivants à vos fichiers de configuration d’autorité de certification:

[ policy_match ]
organizationName = match

Si vous souhaitez autoriser le changement du nom de l'organisation , utilisez:

[ policy_match ]
organizationName = supplied

Il existe d'autres règles concernant le traitement des noms DNS dans les certificats X.509/PKIX. Reportez-vous à ces documents pour les règles:

Les documents RFC 6797 et RFC 7469 sont répertoriés, car ils sont plus restrictifs que les autres documents RFC et CA/B. Les RFC 6797 et 7469 n'autorisent pas une adresse IP non plus.

405
jww

En plus de la réponse de @jww, je voudrais dire que la configuration dans openssl-ca.cnf,

default_days     = 1000         # How long to certify for

définit le nombre de jours par défaut pendant lesquels le certificat signé par cette racine-ca sera valide. Pour définir la validité de root-ca, vous devez utiliser l'option '-days n' dans:

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

Faute de quoi, votre racine-ca ne sera valide que pendant un mois par défaut et tout certificat signé par cette autorité de certification racine aura également une validité d'un mois.

9
humble_wolf