web-dev-qa-db-fra.com

aider à comprendre la vérification du certificat client

Je crée une API à laquelle seuls certains ordinateurs devraient avoir accès. La communication se fera via SSL entre le serveur et les clients. Afin de vérifier qu'un client a accès, je voudrais créer un certificat pour chaque client, qui est signé par le serveur. Tout client qui ne fournit pas le certificat signé par le serveur doit se voir refuser l'accès.

J'ai un certificat SSL et une clé de GoDaddy. Je pensais que je devrais pouvoir créer des certificats clients en utilisant ces informations, mais partout où je regarde, il semble que j'ai besoin du certificat CA (de GoDaddy) pour signer le certificat client et non le certificat/la clé de mon serveur spécifique.

Cela n'a pas de sens pour moi, car il semble étrange que je doive aller chez GoDaddy et obtenir un nouveau certificat pour chaque client. J'imagine que ce n'est pas le cas et que je fais quelque chose de mal ou que je ne comprends pas complètement.

Donc - Comment puis-je créer un certificat client signé par mon certificat/mot de passe serveur?

Si vous pouviez fournir des commandes (j'utilise openssl) pour générer le certificat client à partir de mon certificat serveur, ce serait également très apprécié.

Merci!

20
zsalzbank

Pour signer des certificats clients, vous aurez besoin d'un certificat CA que vous contrôlez. Il n'est pas question dans la plupart des cas d'en payer un, car les certificats d'autorité de certification de confiance mondiale constituent un risque pour la sécurité du reste d'Internet. Dans ces cas, vous devez donc créer votre propre autorité de certification et créer vos propres certificats de serveur et de client.

Commençons donc avec un fichier de base openssl.conf que nous utiliserons pour la génération de tous ces certificats:

[ ca ]
default_ca  = CA_default                # The default ca section

[ CA_default ]
certs          = certs                  # Where the issued certs are kept
crl_dir        = crl                    # Where the issued crl are kept
database       = database.txt           # database index file.
new_certs_dir  = certs                  # default place for new certs.
certificate    = cacert.pem             # The CA certificate
serial         = serial.txt             # The current serial number
crl            = crl.pem                # The current CRL
private_key    = private\cakey.pem      # The private key
RANDFILE       = private\private.rnd    # private random number file

x509_extensions  = v3_usr               # The extentions to add to the cert
default_days     = 365
default_crl_days = 30                   # how long before next CRL
default_md       = sha256               # which md to use.
preserve         = no                   # keep passed DN ordering
policy           = policy_match
email_in_dn      = 

[ policy_match ]
commonName      = supplied

[ req ]
default_bits        = 2048
default_keyfile     = privkey.pem
distinguished_name  = req_distinguished_name
x509_extensions     = v3_ca

[ v3_ca ]
basicConstraints     = CA:TRUE
subjectKeyIdentifier = hash

[ v3_usr ]
basicConstraints     = CA:FALSE
subjectKeyIdentifier = hash

[ server ]
basicConstraints       = CA:FALSE
nsCertType             = server
nsComment              = "Server Certificate"
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer:always
extendedKeyUsage       = serverAuth
keyUsage               = digitalSignature, keyEncipherment

[ client ]
basicConstraints       = CA:FALSE
nsCertType             = client
nsComment              = "Client Certificate"
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer:always
extendedKeyUsage       = clientAuth
keyUsage               = digitalSignature

[ req_distinguished_name ]

Ce fichier de configuration est conçu pour la génération automatique de certificats à partir d'un script batch. Si vous avez besoin de plus de contrôle ou d'options de dénomination, vous devez l'adapter à votre situation.

Donc pour générer une CA, allez dans le répertoire où vous voulez faire votre CA, mettez-y openssl.conf et:

PASSWORD="PUT_YOUR_CA_PASSWORD_HERE"

# Make the config CA specific
cat openssl.conf > use.conf
echo "CN=PUT_CA_NAME_HERE" >> use.conf

# Create the necessary files
mkdir keys requests certs 
touch database.txt
echo 01 > serial.txt

# Generate your CA key (Use appropriate bit size here for your situation)
openssl genrsa -aes256 -out keys/ca.key -passout pass:$PASSWORD 2048

# Generate your CA req
openssl req -config use.conf -new -key keys/ca.key -out requests/ca.req -passin pass:$PASSWORD

# Make your self-signed CA certificate
openssl ca  -config use.conf -selfsign -keyfile keys/ca.key -out certs/ca.crt -in requests/ca.req -extensions v3_ca -passin pass:$PASSWORD -batch

# Cleanup
rm requests/ca.req use.conf

Maintenant, pour générer un certificat serveur (par exemple pour votre serveur Web):

PASSWORD="PUT_YOUR_CA_PASSWORD_HERE"
NAME="PUT_THE_NAME_OF_SERVER_TO_GENERATE_HERE"

# Make the config Server specific
cat openssl.conf > use.conf
echo "CN=$NAME" >> use.conf

openssl req -new -nodes -extensions server -out "requests/$NAME.req" -keyout "$NAME.key" -config use.conf -passin pass:$PASSWORD )
openssl ca -batch -extensions server -keyfile keys/ca.key -cert certs/ca.crt -config use.conf -out "certs/$NAME.crt" -passin pass:$PASSWORD -infiles "requests/$NAME.req"

# Cleanup
rm "requests/$NAME.req" use.conf

Maintenant, pour générer un certificat client:

PASSWORD="PUT_YOUR_CA_PASSWORD_HERE"
NAME="PUT_THE_NAME_OF_CLIENT_TO_GENERATE_HERE"

# Make the config Client specific
cat openssl.conf > use.conf
echo "CN=$NAME" >> use.conf

openssl req -new -nodes -extensions client -out "requests/$NAME.req" -keyout "$NAME.key" -config use.conf -passin pass:$PASSWORD )
openssl ca -batch -extensions client -keyfile keys/ca.key -cert certs/ca.crt -config use.conf -out "certs/$NAME.crt" -passin pass:$PASSWORD -infiles "requests/$NAME.req"

# Cleanup
rm "requests/$NAME.req" use.conf

La seule différence entre la génération de clés et de certificats pour les clients et les serveurs pour éviter qu'un certificat client volé ne puisse également être utilisé pour lire un serveur et pour `` tromper '' d'autres clients pour s'y connecter (cela ne fonctionne que tant que vos applications prennent en charge le client et extension de serveur dans les certificats).

19
Paul

Une autorité de certification est une entité qui délivre des certificats. Vous voulez émettre des certificats (aux clients), donc vous voulez être un CA.

Quiconque essaie de valider un certificat doit faire confiance à la clé CA (c'est a priori confiance: pensez à la clé publique CA étant codée en dur dans le logiciel ou le système d'exploitation). Dans votre cas, vous souhaitez que votre serveur valide les certificats, votre serveur devra donc conserver une copie de la clé publique de l'autorité de certification.

Une autorité de certification existante comme GoDaddy a réussi à obtenir une copie de sa clé publique dans tous les navigateurs Web - leur autorité de certification est approuvée par tout le monde. Pour y parvenir, ils devaient prouver aux fournisseurs de navigateurs (par exemple Microsoft) qu'ils étaient fiables et sérieux (la clé privée est dans un bunker, ils ont des procédures pour tout, ils ont une sauvegarde financière suffisante pour assurer la continuité des opérations ...) et c'était cher, c'est pourquoi ils ne vous donneront pas de puissance sous-CA gratuitement (ou même pas cher). Cependant, dans votre situation, peu vous importe que la clé CA soit connue du monde entier: vous n'avez besoin que d'une CA à laquelle votre serveur (que vous contrôlez entièrement) fera confiance. Un CA que vous maintenez vous-même ira bien.

EJBCA est une implémentation CA open source gratuite qui devrait être facile à utiliser. Alternativement, vous pouvez regrouper quelques scripts OpenSSL .

Remarque: les certificats sont pour authentification, pas pour autorisation. Ils sont destinés à identifier les utilisateurs. Je vous suggère de séparer les deux rôles sur votre serveur:

  • Lorsque vous émettez un certificat au client X, mettez le nom "X" dans le certificat.
  • Gardez sur le serveur une table des "clients autorisés" (par nom).
  • Lorsqu'un client se connecte, validez son certificat, puis extrayez le nom du client du certificat et vérifiez le nom dans le tableau des clients autorisés.

Cette séparation sera extrêmement utile le jour où vous souhaitez révoquer les droits d'accès d'un client donné.

10
Thomas Pornin

Pour autant que je sache, vous ne pouvez pas créer un certificat client valide avec votre SSL que vous avez acheté chez GoDaddy. La raison derrière cela a à voir avec la clé privée du certificat CA de GoDaddy, qu'ils ne donneront pas pour une bonne raison.

Maintenant, si vous avez tous les ordinateurs sous votre contrôle, la chose la plus simple et la moins chère à faire serait de générer votre propre certificat CA et de signer vos clients. Ajoutez votre autorité de certification à chacun des magasins racine de confiance sur chaque ordinateur individuel.

Vous pouvez obtenir une autorité de certification pour signer un certificat qui vous permet d'être une autorité de certification, cependant, ces certificats ne sont pas bon marché, comme dans "contactez-nous pour un devis".

Si vous avez besoin d'un outil, je crois XCA est une interface graphique qui vous facilitera la tâche.

1
Travis Pessetto