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

195

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

  1. Utilisation du x509module:

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

    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. Veuillez conseiller une utilisation correcte si je dois l'utiliser.

De quelle manière doit-on utiliser pour signer les demandes de certificat avec votre autorité de certification? Une méthode est-elle meilleure que l'autre (par exemple, une étant obsolète)?

Bernard Rosset
la source
1
J'aime ce petit script qui met en place une autorité de certification et vous permet de générer des certificats "subordonnés" signés. Notez que si vous voulez que votre système soit satisfait des certificats (comme pour S / MIME ou autre), vous devez ajouter le certificat CA en tant que "racine de confiance".
jar
D'après ce que je peux voir, cac'est pour les cas où vous êtes plus sérieux au sujet de devenir CA.
x-yuri
Vous pourriez trouver ma réponse intéressante.
x-yuri
Stack Overflow est un site de questions de programmation et de développement. Cette question semble être hors sujet car elle ne concerne pas la programmation ou le développement. Voir Quels sujets puis-je poser ici dans le centre d'aide. Peut-être que Super User ou Unix & Linux Stack Exchange seraient un meilleur endroit pour demander.
2018 à 4h01

Réponses:

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

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

Il vous manque le prélude à ces commandes.

Il s'agit d'un processus en deux étapes. Vous configurez d'abord votre autorité de certification, puis vous signez un certificat d'entité finale (aka serveur ou utilisateur). Les deux commandes élident les deux étapes en une seule. Et les deux supposent que vous disposez d'un fichier de configuration OpenSSL déjà configuré pour les certificats d'autorité de certification et de serveur (entité finale).


Créez d'abord un fichier de configuration de base :

$ touch openssl-ca.cnf

Ajoutez-y ensuite:

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 sont tirés d'un plus complexe openssl.cnf(vous pouvez le trouver dans /usr/lib/openssl.cnf), mais je pense qu'ils sont les éléments essentiels pour créer le certificat CA et la clé privée.

Ajustez les champs ci-dessus à votre goût. Les valeurs par défaut vous font gagner du temps lors de la saisie des mêmes informations lors de l'expérimentation du fichier de configuration et des options de commande.

J'ai omis les éléments pertinents pour la liste de révocation de certificats, mais vos opérations d'autorité de certification devraient les avoir. Voir openssl.cnfet la crl_extsection associée .

Ensuite, exécutez ce qui suit. Le -nodesomet le mot de passe ou la phrase secrète pour que vous puissiez examiner le certificat. C'est une très 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

Après l'exécution de la commande, cacert.pemsera votre certificat pour les opérations de l'autorité de certification et cakey.pemsera la clé privée. Rappelez-vous 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 pour le Any Purpose: Yes; voir "Critique, CA: FAUX" mais "CA à tout usage: Oui" ).

$ 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 facilement digestible. Tout d'abord, touchle openssl-server.cnf(vous pouvez également en créer un pour les certificats utilisateur).

$ touch openssl-server.cnf

Ensuite, 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 poste de travail en tant que serveur, vous devrez peut-être effectuer les opérations suivantes pour Chrome. Sinon, Chrome peut se plaindre qu'un nom commun n'est pas valide ( ERR_CERT_COMMON_NAME_INVALID) . Je ne sais pas quelle est la relation entre une adresse IP dans le SAN et un CN dans ce cas.

# IPv4 localhost
IP.1     = 127.0.0.1

# IPv6 localhost
IP.2     = ::1

Ensuite, créez la demande de certificat de serveur. N'oubliez pas d' omettre -x509 *. L'ajout -x509cré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 recevrez une demande servercert.csret une clé privée 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 CA.


Vous êtes presque prêt à signer le certificat du serveur par votre autorité de certification. L'autorité de certification a openssl-ca.cnfbesoin de deux sections supplémentaires avant d'émettre la commande.

Tout d'abord, ouvrez openssl-ca.cnfet 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

Ensuite, ajoutez ce qui suit à la [ CA_default ]section 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). Vous allez maintenant voir comment ils sont utilisés, alors j'espère qu'ils auront du 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, touchez index.txtet 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 émis 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 émis 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

Plus tôt, vous avez ajouté ce qui suit à 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 alternatifs de sujet (SAN) comme www.example.comet mail.example.com.

Si vous utilisez copy_extensions = copy, mais ne regardez pas la demande, le demandeur pourrait être en mesure de vous inciter à signer quelque chose comme une racine subordonnée (plutôt qu'un serveur ou un certificat utilisateur). Ce qui signifie qu'il / elle pourra frapper des certificats qui remonteront à votre racine de confiance. Assurez-vous de vérifier la demande openssl req -verifyavant de signer.


Si vous l' omettez unique_subject ou le définissez yes, vous ne pourrez créer qu'un seul certificat sous le nom distinctif du sujet.

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

La tentative de création d'un deuxième certificat lors de l'expérimentation se traduira par les éléments suivants 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

Il unique_subject = noest donc parfait pour les tests.


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

[ policy_match ]
organizationName = match

Si vous souhaitez autoriser la modification du nom de l' organisation , utilisez:

[ policy_match ]
organizationName = supplied

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

Les RFC 6797 et RFC 7469 sont répertoriées, car elles sont plus restrictives que les autres RFC et documents CA / B. Les RFC 6797 et 7469 ne permettent pas non plus une adresse IP.

jww
la source
4
Merci pour cette réponse détaillée ... Cependant, je suis un peu perdu ici. Ce que j'ai compris de ce que vous avez écrit: openssl reqest utilisé pour générer la CSR, openssl req -x509est utilisé pour générer le certificat CA (j'ai vu dans un autre endroit que vous pourriez également créer un certificat auto-signé), openssl caest utilisé pour signer une CSR avec un certificat CA. Droite? Ce qui m'embrouille aussi, c'est que les mêmes parties du fichier openssl.cnf sont utilisées avec des valeurs différentes selon la commande ... Je pense que je suis totalement perdu maintenant.
Bernard Rosset
27
Tout d'abord, openssl req -x509est utilisé pour créer l'AC. Deuxièmement, openssl reqest utilisé pour créer la CSR du serveur. Troisièmement, openssl caest utilisé pour créer le certificat de serveur et le certifier avec la signature de l'autorité de certification.
jww
1
"Ce qui m'embrouille aussi, c'est que les mêmes parties du fichier openssl.cnf ..." - C'est vrai. Voilà pourquoi je les ai éclatés pour vous dans openssl-ca.cnfet openssl-server.cnf. Après vous être habitué à eux et comment les sections sont invoquées, vous pouvez les combiner en une monstruosité comme openssl.cnf.
2014
1
@JeffPuckettII - C'est une section commune. Il est utilisé à la fois par l'utilitaire CA et l'utilitaire Req. Ce doivent être des extensions v3.
2016
5
@ahnkle Utilisez l'option -days pour tout élément différent des 30 jours par défaut. Documents OpenSSL
George
14

En plus de répondre à @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 ce root-ca sera valide. Pour définir la validité de root-ca lui-même, 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

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

humble_wolf
la source