Il y a quelque temps, il Ă©tait nĂ©cessaire dans le cadre du projet de limiter le nombre simultanĂ© dâordinateurs ayant accĂšs Ă une application Web fonctionnant sur le rĂ©seau local du client.
La dĂ©cision d'utiliser des jetons USB matĂ©riels pour identifier l'ordinateur est venue d'elle-mĂȘme. Le choix reposait sur le Rutoken EDS: il fonctionne sans pilotes, pour fonctionner dans une application Web, seul un plug-in pour le navigateur, Ă©mis par le dĂ©veloppeur, est nĂ©cessaire. Ătant donnĂ© que le jeton doit identifier l'ordinateur et non l'utilisateur, travailler avec lui doit ĂȘtre complĂštement «transparent»: s'il existe, le systĂšme fonctionne simplement en silence sans poser Ă l'utilisateur des questions inutiles.
Il a Ă©tĂ© dĂ©cidĂ©: lors de la connexion au systĂšme, signez les informations d'identification de l'utilisateur avec une signature non qualifiĂ©e d'un certificat stockĂ© sur Rutoken Ă l'aide du plug-in Rootoken, et vĂ©rifiez sur le serveur. AprĂšs une connexion rĂ©ussie Ă l'aide du plug-in, vĂ©rifiez la prĂ©sence physique du mĂȘme jeton et, en son absence, dĂ©connectez-vous du systĂšme. Dans le cadre du projet mentionnĂ©, c'Ă©tait suffisant.
Il est nĂ©cessaire de crĂ©er votre propre autoritĂ© de certification (CA) pour l'Ă©change de messages signĂ©s, ou plutĂŽt pour le transfert de messages signĂ©s du client vers le serveur. Les certificats clients doivent ĂȘtre situĂ©s sur des jetons USB dans des conteneurs de clĂ©s privĂ©es et la vĂ©rification de la signature doit ĂȘtre effectuĂ©e sur le serveur Ă l'aide d'OpenSSL.
Alors, la tĂąche:
installation et configuration sur le serveur Linux de l'AC. Déployez des certificats clients qui identifient les ordinateurs sur des jetons USB .
Pour le résoudre, vous aurez besoin de:
- Nous crĂ©ons un rĂ©pertoire oĂč se trouvera l'autoritĂ© de certification et copions la configuration OpenSSL incluse avec le systĂšme (il y a /etc/ssl/openssl.cnf sur les derniĂšres versions d'Ubuntu)
- Nous configurons "notre" openssl.cnf:
a) Ajoutez au début des directives de fichier pour connecter le moteur de jeton:
openssl_conf = openssl_def [ openssl_def ] engines = engine_section [ engine_section ] rtengine = gost_section [ gost_section ] dynamic_path = /path/to/rutoken/openssl/connector/librtengine.so MODULE_PATH = /path/to/rutoken/pkcs11/librtpkcs11ecp.so RAND_TOKEN = pkcs11:manufacturer=Aktiv%20Co.;model=Rutoken%20ECP default_algorithms = CIPHERS, DIGEST, PKEY, RAND
b) décommenter la ligne
# req_extensions = v3_req # The extensions to add to a certificate request
c) dans la section [v3_req] , spécifiez les paramÚtres suivants:
subjectSignTool = ASN1:FORMAT:UTF8,UTF8String: extendedKeyUsage=emailProtection keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
d) dans la section [v3_ca], supprimez l'option critique du paramĂštre basicConstraints:
basicConstraints = CA:true
Pour quoi? RĂ©ponse honnĂȘte: je ne sais pas. Cependant, tous les exemples de certificats racine que j'ai tĂ©lĂ©chargĂ©s en essayant de comprendre le sujet Ă©taient sans signe critique. Je pose la question "pour quoi?" collĂšgues plus expĂ©rimentĂ©s.
e) définir éventuellement les valeurs par défaut qui seront proposées lors de l'émission de certificats auto-signés et lors de la génération de demandes d'émission de certificats clients. Ces paramÚtres se trouvent dans la section [req_distinguished_name]
Le paramÚtre avec le suffixe _default est la valeur par défaut. Un exemple:
countryName = Country Name (2 letter code) countryName_default = AU countryName_min = 2 countryName_max = 2
Lorsque le systÚme vous demande d'entrer le paramÚtre countryName , il indiquera entre crochets qu'il laissera la valeur AU par défaut.
Ceci termine la configuration de la configuration OpenSSL. Il reste à indiquer à OpenSSL qu'il est nécessaire de l'utiliser. Pour ce faire, définissez la variable d'environnement OPENSSL_CONF:
export OPENSSL_CONF=/path/to/your/openssl.cnf
- Nous crĂ©ons une structure de rĂ©pertoires oĂč les informations sur notre autoritĂ© de certification seront stockĂ©es.
Pour ce faire, accĂ©dez au rĂ©pertoire créé avec openssl.cnf qui vient d'ĂȘtre modifiĂ© et procĂ©dez comme suit:
a) créez-y des sous-répertoires:
demoCA
demoCA / privé
demoCA / newcerts
Remarque: le nom demoCA est énoncé dans la section [CA_default] du fichier openssl.cnf . Vous pouvez le modifier (à l'étape 2), puis travailler avec lui au lieu de demoCA.
b) dans le rĂ©pertoire demoCA, crĂ©ez un fichier index.txt vide et un fichier sĂ©rie , que nous ouvrons avec un Ă©diteur de texte et y Ă©crivons la ligne 01. C'est le compteur des certificats Ă©mis. AprĂšs l'Ă©mission de chaque certificat suivant, la valeur de ce fichier augmente d'une unitĂ©. - Nous pouvons Ă©ventuellement formater notre jeton Ă l'aide de l'utilitaire rtAdmin. Maintenant, tout est prĂȘt pour le dĂ©ploiement de l'autoritĂ© de certification.
L'algorithme d'action est globalement simple:
a) nous émettons le certificat racine du centre de certification en utilisant l'algorithme GOST:
- générer une clé privée pour émettre un certificat CA auto-signé
- générer un certificat X509 auto-signé à l'aide de la clé générée
b) sur chacun des jetons USB
- générer une paire de clés (le soi-disant conteneur de clés privées)
- générer une demande de signature de certificat à l'aide de la clé de jeton générée
- émettre un certificat pour cette demande
- enregistrer le certificat sur le jeton dans le conteneur de clé privée
Voici une implémentation de cet algorithme pour un seul jeton:
Génération de clé privée pour le certificat CA (nous utilisons l'algorithme GOST):
openssl genpkey -algorithm gost2012_256 -pkeyopt paramset:A -outform PEM -out demoCA/private/cakey.pem
Nous émettons un certificat CA auto-signé:
<b>openssl req -new -x509 -key demoCA/private/cakey.pem -out demoCA/certs/cacert.pem -extensions v3_ca -days +3650 -outform PEM
Remarque: nous avons indiqué sur la ligne de commande qu'il est nécessaire d'utiliser les extensions v3_ca de la configuration openssl_cnf. C'est là que c'est notre CA. Validité de 10 ans. Une chose courante pour CA. Mais plus est possible.
Dans le processus de délivrance d'un certificat, le systÚme vous demandera de saisir les valeurs des paramÚtres qui se trouvent dans la section [req_distinguished_name] de notre fichier openssl.cnf
Nous commençons maintenant les opérations de jeton. Si le jeton est nouveau ou formaté avec des valeurs par défaut, le code PIN de l'utilisateur est 12345678. Je pars de l'hypothÚse que c'est exactement le cas. Sinon, vous devez spécifier le code PIN utilisateur correct et généralement essayer de vous assurer que dans les exemples ci-dessous, les noms des objets déjà existants sur le jeton ne chevauchent pas ceux saisis.
Tout d'abord, nous allons générer une paire de clés. OpenSSL n'est pas en mesure d'effectuer cette opération sur Rutoken, nous allons donc utiliser l'utilitaire pkcs11-tool du package OpenSC:
pkcs11-tool --module /path/to/your/librtpkcs11ecp.so --login --pin 12345678 --keypairgen --key-type GOSTR3410:A --id 303030303031 --label 'client01'
Remarque importante: nous avons spécifié l'ID 303030303031. Tous les deux chiffres de cet identifiant ne sont rien de plus que le code ASCII des caractÚres «0» et «1», respectivement. Pour les opérations avec OpenSSL, cela ressemblera à "id = 000001"
Générez une demande de certificat:
openssl req -utf8 -new -keyform engine -key 'pkcs11:id=000001' -engine rtengine -out demoCA/newcerts/client01.csr
Si tout a été fait correctement, alors le systÚme
- demander un code PIN
- demandera des paramĂštres de nom de certificat (dans la section [req_distinguished_name] )
- émettra un fichier de demande de signature de certificat
à l'aide de cette demande, nous signons un certificat client ( dans l'exemple, le certificat est valable 1825 jours. Il est important que cette période ne dépasse pas la période de validité de votre certificat racine ):
openssl ca -utf8 -days +1825 -keyfile demoCA/private/cakey.pem -cert demoCA/certs/cacert.pem -in demoCA/newcerts/client01.csr -outdir demoCA/newcerts -out demoCA/certs/client01.pem
Le systÚme affichera le certificat, posera des questions sur la décision de le signer (réponse «y») et sur la décision de sauvegarder le nouveau certificat (répondez à nouveau «y»).
Nous enregistrons le certificat reçu pour le jeton:
pkcs11-tool --module /path/to/your/librtpkcs11ecp.so --login --pin 12345678 --id=303030303031 -w demoCA/certs/client01.pem -y cert
Câest tout.
Tester le «miracle» créé. Pour ce faire, nous signons et vérifions la signature de la phrase "Bonjour tout le monde!":
echo Hello,world! | openssl cms -nodetach -sign -signer demoCA/certs/client01.pem -keyform engine -inkey "pkcs11:id=000001" -engine rtengine -binary -noattr -outform PEM | openssl cms -verify -CAfile demoCA/certs/cacert.pem -inform PEM
Si tout est fait correctement, le systÚme demandera un code PIN, signera le message, puis vérifiera la signature et, en cas de succÚs, affichera le message d'origine et le résultat de la vérification («succÚs»)
Remarque . Revenant à la tùche de titre et signant à l'aide du plugin, il convient de noter que par défaut le plugin donne le résultat de la signature non pas au format PEM, mais au format DER, encodé en base64. Par conséquent, pour vérifier la signature, vous devez d'abord décoder à partir de base64, et lors de la vérification, spécifiez le format DER d'entrée.
Bonne chance!