Dans ce chapitre, nous allons créer notre propre autorité de certification x509 DCI et notre premier certificat machine !
Auparavant, nous avons vu dans les chapitres précédents l'essentiel de ce qu'il faut savoir sur les certificats x509 DCI et l'autorité de certification x509 DCI.
Pour rappel, la cryptographie RSA nécessite une paire de clefs : chaque player ou encoder possède deux clefs : une clef privée et une clef publique. La clef privée servira pour déchiffrer ou signer. La clef publique peut être diffusée à n'importe qui pour servir à chiffrer ou à vérifier une signature.
Pour diffuser une clef publique, nous pourrions le faire en émettant simplement les nombres cryptographiques publics nécessaires au RSA (modulus et exponent). Mais la communauté a créé un containeur pour ce cas de figure : des certificats.
Ces certificats permettent d'avoir non seulement les nombres cryptographiques publics RSA mais également ajouter des métadonnées afin de connaître l'identité et rôle de la clef publique - agrémenté d'une signature pour valider son authenticité.
Maintenant que nous avons effectué ce petit préambule, démarrons la création de notre chaîne de certificats.
Comme nous avons vu dans la partie la chaîne de certification, nous avons toute une structure à créer pour avoir cette fameuse chaîne de certificat - voyez cela comme un arbre inversé.
Pour respecter le workflow DCI, nous devons créer au moins 3 niveaux de certificats :
Voici une hiérarchie simple d'une chaîne de certification :
+------------+ --.
| ROOT | (self-signed) |
+-----++-----+ |
|| |-- Certificate Authority (CA)
+------++------+ |
| INTERMEDIATE | (signed by ROOT) |
+------++------+ --'
||
+---------+
| LEAF | (signed by INTERMEDIATE)
+---------+
La meilleure analogie est celle de l'arbre inversé : tout en haut, vous avez la racine de l'arbre - appelé root certificate - c'est elle qui va tout contrôler. Les certificats intermédiaires sont les branches de l'arbre. Et enfin, les certificats en toute fin sont appelés leaf certificate pour ... certificat feuille :)
Le certificat au dessus est le parent (appelé Issuer), celui qui va signer ses certificats en lien direct avec lui, ses enfants.
Toute la partie haute (root et intermediate) fait partie de la chaine de certification, plus connu sous le terme Certificate Authority ou abrégé en CA. C'est cette partie qui a le droit de vie (et de mort) sur les certificats en dessous. Ainsi, un certificat racine ou intermédiaire pourra créer et signer d'autres certificats, un leaf ne pourra jamais.
Maintenant que nous avons (re)vu cela, commençons par le début : nous allons créer notre premier certificat de notre chaîne en commençant par le plus important : le certificat racine (Root Certificate).
Ce certificat a une particularité par rapport aux autres certificats de l'autorité de certification : c'est le seul à ne pas avoir de parent. Pour sa création, il a donc une particularité par rapport aux autres certificats : celui de se signer lui-même, il est dit certificat auto-signé ou plus connu par le terme self-signed certificate.
Avec cette particularité, sur sa fiche d'identification, nous retrouverons donc avec un Subject, un Issuer et un DirName avec les mêmes valeurs dans leurs attributs.
Voici les étapes que nous appliquerons pour chaque certificat :
Durant chaque étape, vous aurez le choix entre générer vous-même les fichiers. Vous avez également la possibilité d'analyser nos exemples qui seront accessibles via des liens directs.
Procédons à la toute première étape : la création des clefs privée et publique RSA pour notre certificat racine.
Nous allons demander à OpenSSL de générer notre fichier RSA - surnommé keypair - qui va contenir énormément d'informations : la partie privée et la partie publique - avec son modulus, ses primes, exponents, … (pour plus d'infos, voir notre chapitre RSA) :
# generate RSA priv/pub keys (2048-bits)
openssl genrsa -out root.key 2048
Notre fichier root.key
contient maintenant nos données RSA enveloppées dans notre format PEM (en base64) et PKCS#8 :
# cat root.key
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDdCgZIs0uA30mC
2kCrGihgjWEuvQho1wecCs3QlKXqbpT32ho9emIt2Hk6xRLWfFqyI4wMG64UdS4h
aFvRFNSS4/tB+P91lNEwdT99QnI0j7dwpUPt+ukIZLDLJtB3eA8dtl4MaMpE2hwS
KplfSPN+scc2r+7/iNZCXbaT4wX0LikWvuT87FgGBD3eggRuqHpZ7tr/jhB6Fy/1
KfbiO+y6/fDBOwuwDcSrCoaMqY7HHG5Wid/dWnvBTqEs0ZyPfwhDDiLbNZ2bU1Qb
MGQCuNhOdF6I/KSYmA50c2BGCtyLwy4i9t4t8uCp540ierMyfz8XNwmIRS1ra/GO
PPkZMLblAgMBAAECggEAHhUj2c0dCi2uvDJRTs1r5V1ty9tKQ7UlgfqDxvlpbfMd
hHCYgE7MVzT4+s32IbQhm9D0BHSCnUzSub/m5G5op+fYkEKqcdQ5IYEzjNai4xMU
LNkxL42lyCX8BwoB9osjyNrDCKlSWKCJOtJgC/R1FIRuz7s4qb/JI+shKBYOVLbw
HRaA+oKjihVYMKsw3o7TYtIQblAUIbgrM+tzO63Yy2nPiTy75Zb9ueyUpVTAvsOW
0dLpojxjzPZh4JIV8CnPUSKKE8MNt+kD0cbkrBVQ8UFU0kYGW41z7LXAxwPBx1zN
96KXKJ9fc3BmVQZxOSSf/i9V+WpNrldZ5Wbm+LAt2QKBgQD2bLi2xScSnsQUjHJe
YdUTd26iy6n/aYZhy2I3N67BWAfj2D7+I5UbVY34+KlPQLydbFGqL3IOlF2Q7k0y
7jA7ZZsmuq6DTVYkQ04OLuz0VK3LEg5HzrEUM3ii5q21yKNIds+7uk2xzX2k0VeQ
oSZUyOaXqfrQ9cak7OFWMw2B9wKBgQDloMiamsiFxSMgZ0yMOczvoTrXH2vomeKU
JRyiZXbTcljVY9u9k5U/tF2TvfEcT+1Ytb3NjgxhCzPMrBUN+AhN/tyv5+VCXRpz
hK+ngOMcBfTcL9dm8SvvHOausYfzmlAsa0pH66QvmmKMGvbofMg54c2FsG+zBkXK
255d2r0XAwKBgBO+hFJIm6fXRriqxCMhzZPAtwGeNeG8D8NYK2dnM75UElXEJs/w
A+trwHNZYR9zfWlTm3t6T7YxVwncvhy9junDa1oADSmCEcvYBLIIOn4dJsulh7Vj
LzcCJMFQoEx3ZfXRZzWQaNc9Mrr49v4km1ChxDAUs374olDmlet1LbjjAoGBAOKA
r3+5MBSreVOsMVicZyb0DbtG9kURDet9k/ooRYaa4z9R6d3c5rpY6nkiQePgf0ki
tB8/f7x1tVmtYHNP9rkgrYUiJAVLGx1Zg36hZuQsh/RtiHa1a9XH10/4NBc5Xt4B
0tqQeHqwOYbjzitTcpmNvxGhEP0xMcTAzzza1+wLAoGAM6OaghOKkUX4aYYv4tO0
7E64+8go2eERs9X/q16PWr/efjFYWTzQqb9Eorx7QZVZgIiVPjXR18BxPjJSus31
ssB9N+pRBunMLBCxgpftfR5TigrGfJeCp4SzivuxOdLu5whYkuyfsveDZAJAWC7f
5DMY3QBlngNQpknO6GwXSxE=
-----END PRIVATE KEY-----
Analysons rapidement le fichier via le parseur ASN.1 :
# openssl asn1parse -in root.key
0:d=0 hl=4 l=1213 cons: SEQUENCE
4:d=1 hl=2 l= 1 prim: INTEGER :00
7:d=1 hl=2 l= 13 cons: SEQUENCE
9:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
20:d=2 hl=2 l= 0 prim: NULL
22:d=1 hl=4 l=1191 prim: OCTET STRING [HEX DUMP]:308204A3020100028201010(...)
Tout semble correct.
Voyons ce que nous avons dedans à l'aide de l'analyseur RSA :
# openssl rsa -check -in root.key -noout -text
Private-Key: (2048 bit, 2 primes)
modulus:
00:dd:0a:06:48:b3:4b:80:df:49:82:da:40:ab:1a:
28:60:8d:61:2e:bd:08:68:d7:07:9c:0a:cd:d0:94:
a5:ea:6e:94:f7:da:1a:3d:7a:62:2d:d8:79:3a:c5:
12:d6:7c:5a:b2:23:8c:0c:1b:ae:14:75:2e:21:68:
5b:d1:14:d4:92:e3:fb:41:f8:ff:75:94:d1:30:75:
3f:7d:42:72:34:8f:b7:70:a5:43:ed:fa:e9:08:64:
b0:cb:26:d0:77:78:0f:1d:b6:5e:0c:68:ca:44:da:
1c:12:2a:99:5f:48:f3:7e:b1:c7:36:af:ee:ff:88:
d6:42:5d:b6:93:e3:05:f4:2e:29:16:be:e4:fc:ec:
58:06:04:3d:de:82:04:6e:a8:7a:59:ee:da:ff:8e:
10:7a:17:2f:f5:29:f6:e2:3b:ec:ba:fd:f0:c1:3b:
0b:b0:0d:c4:ab:0a:86:8c:a9:8e:c7:1c:6e:56:89:
df:dd:5a:7b:c1:4e:a1:2c:d1:9c:8f:7f:08:43:0e:
22:db:35:9d:9b:53:54:1b:30:64:02:b8:d8:4e:74:
5e:88:fc:a4:98:98:0e:74:73:60:46:0a:dc:8b:c3:
2e:22:f6:de:2d:f2:e0:a9:e7:8d:22:7a:b3:32:7f:
3f:17:37:09:88:45:2d:6b:6b:f1:8e:3c:f9:19:30:
b6:e5
publicExponent: 65537 (0x10001)
privateExponent:
1e:15:23:d9:cd:1d:0a:2d:ae:bc:32:51:4e:cd:6b:
e5:5d:6d:cb:db:4a:43:b5:25:81:fa:83:c6:f9:69:
6d:f3:1d:84:70:98:80:4e:cc:57:34:f8:fa:cd:f6:
21:b4:21:9b:d0:f4:04:74:82:9d:4c:d2:b9:bf:e6:
e4:6e:68:a7:e7:d8:90:42:aa:71:d4:39:21:81:33:
8c:d6:a2:e3:13:14:2c:d9:31:2f:8d:a5:c8:25:fc:
07:0a:01:f6:8b:23:c8:da:c3:08:a9:52:58:a0:89:
3a:d2:60:0b:f4:75:14:84:6e:cf:bb:38:a9:bf:c9:
23:eb:21:28:16:0e:54:b6:f0:1d:16:80:fa:82:a3:
8a:15:58:30:ab:30:de:8e:d3:62:d2:10:6e:50:14:
21:b8:2b:33:eb:73:3b:ad:d8:cb:69:cf:89:3c:bb:
e5:96:fd:b9:ec:94:a5:54:c0:be:c3:96:d1:d2:e9:
a2:3c:63:cc:f6:61:e0:92:15:f0:29:cf:51:22:8a:
13:c3:0d:b7:e9:03:d1:c6:e4:ac:15:50:f1:41:54:
d2:46:06:5b:8d:73:ec:b5:c0:c7:03:c1:c7:5c:cd:
f7:a2:97:28:9f:5f:73:70:66:55:06:71:39:24:9f:
fe:2f:55:f9:6a:4d:ae:57:59:e5:66:e6:f8:b0:2d:
d9
prime1:
00:f6:6c:b8:b6:c5:27:12:9e:c4:14:8c:72:5e:61:
d5:13:77:6e:a2:cb:a9:ff:69:86:61:cb:62:37:37:
ae:c1:58:07:e3:d8:3e:fe:23:95:1b:55:8d:f8:f8:
a9:4f:40:bc:9d:6c:51:aa:2f:72:0e:94:5d:90:ee:
4d:32:ee:30:3b:65:9b:26:ba:ae:83:4d:56:24:43:
4e:0e:2e:ec:f4:54:ad:cb:12:0e:47:ce:b1:14:33:
78:a2:e6:ad:b5:c8:a3:48:76:cf:bb:ba:4d:b1:cd:
7d:a4:d1:57:90:a1:26:54:c8:e6:97:a9:fa:d0:f5:
c6:a4:ec:e1:56:33:0d:81:f7
prime2:
00:e5:a0:c8:9a:9a:c8:85:c5:23:20:67:4c:8c:39:
cc:ef:a1:3a:d7:1f:6b:e8:99:e2:94:25:1c:a2:65:
76:d3:72:58:d5:63:db:bd:93:95:3f:b4:5d:93:bd:
f1:1c:4f:ed:58:b5:bd:cd:8e:0c:61:0b:33:cc:ac:
15:0d:f8:08:4d:fe:dc:af:e7:e5:42:5d:1a:73:84:
af:a7:80:e3:1c:05:f4:dc:2f:d7:66:f1:2b:ef:1c:
e6:ae:b1:87:f3:9a:50:2c:6b:4a:47:eb:a4:2f:9a:
62:8c:1a:f6:e8:7c:c8:39:e1:cd:85:b0:6f:b3:06:
45:ca:db:9e:5d:da:bd:17:03
exponent1:
13:be:84:52:48:9b:a7:d7:46:b8:aa:c4:23:21:cd:
93:c0:b7:01:9e:35:e1:bc:0f:c3:58:2b:67:67:33:
be:54:12:55:c4:26:cf:f0:03:eb:6b:c0:73:59:61:
1f:73:7d:69:53:9b:7b:7a:4f:b6:31:57:09:dc:be:
1c:bd:8e:e9:c3:6b:5a:00:0d:29:82:11:cb:d8:04:
b2:08:3a:7e:1d:26:cb:a5:87:b5:63:2f:37:02:24:
c1:50:a0:4c:77:65:f5:d1:67:35:90:68:d7:3d:32:
ba:f8:f6:fe:24:9b:50:a1:c4:30:14:b3:7e:f8:a2:
50:e6:95:eb:75:2d:b8:e3
exponent2:
00:e2:80:af:7f:b9:30:14:ab:79:53:ac:31:58:9c:
67:26:f4:0d:bb:46:f6:45:11:0d:eb:7d:93:fa:28:
45:86:9a:e3:3f:51:e9:dd:dc:e6:ba:58:ea:79:22:
41:e3:e0:7f:49:22:b4:1f:3f:7f:bc:75:b5:59:ad:
60:73:4f:f6:b9:20:ad:85:22:24:05:4b:1b:1d:59:
83:7e:a1:66:e4:2c:87:f4:6d:88:76:b5:6b:d5:c7:
d7:4f:f8:34:17:39:5e:de:01:d2:da:90:78:7a:b0:
39:86:e3:ce:2b:53:72:99:8d:bf:11:a1:10:fd:31:
31:c4:c0:cf:3c:da:d7:ec:0b
coefficient:
33:a3:9a:82:13:8a:91:45:f8:69:86:2f:e2:d3:b4:
ec:4e:b8:fb:c8:28:d9:e1:11:b3:d5:ff:ab:5e:8f:
5a:bf:de:7e:31:58:59:3c:d0:a9:bf:44:a2:bc:7b:
41:95:59:80:88:95:3e:35:d1:d7:c0:71:3e:32:52:
ba:cd:f5:b2:c0:7d:37:ea:51:06:e9:cc:2c:10:b1:
82:97:ed:7d:1e:53:8a:0a:c6:7c:97:82:a7:84:b3:
8a:fb:b1:39:d2:ee:e7:08:58:92:ec:9f:b2:f7:83:
64:02:40:58:2e:df:e4:33:18:dd:00:65:9e:03:50:
a6:49:ce:e8:6c:17:4b:11
RSA key ok
Nous avons les données RSA avec son modulus, ses exposants, ses primitives, etc.
Notre fichier RSA root.key
est prêt à l'usage !
Avant de pouvoir générer notre certificat public, nous devons ajouter une étape importante, celle de calculer en amont notre dnQualifier à partir de sa clef publique. Sans cela, notre certificat sera invalide dans un workflow DCI valide.
Pour bien comprendre chaque étape de ce processus, nous allons d'abord générer notre clef publique temporairement 1 depuis notre fichier RSA root.key
# extract public key from root.key
openssl rsa -in root.key -outform PEM -pubout -out root.pub
Notre clef publique se trouve maintenant dans root.pub
:
# cat root.pub
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3QoGSLNLgN9JgtpAqxoo
YI1hLr0IaNcHnArN0JSl6m6U99oaPXpiLdh5OsUS1nxasiOMDBuuFHUuIWhb0RTU
kuP7Qfj/dZTRMHU/fUJyNI+3cKVD7frpCGSwyybQd3gPHbZeDGjKRNocEiqZX0jz
frHHNq/u/4jWQl22k+MF9C4pFr7k/OxYBgQ93oIEbqh6We7a/44Qehcv9Sn24jvs
uv3wwTsLsA3EqwqGjKmOxxxuVonf3Vp7wU6hLNGcj38IQw4i2zWdm1NUGzBkArjY
TnReiPykmJgOdHNgRgrci8MuIvbeLfLgqeeNInqzMn8/FzcJiEUta2vxjjz5GTC2
5QIDAQAB
-----END PUBLIC KEY-----
A l'intérieur, un container ASN.1 avec son modulus et son exposant public RSA (voir tableau en préambule) :
# openssl asn1parse -in root.pub -dump
0:d=0 hl=4 l= 290 cons: SEQUENCE
4:d=1 hl=2 l= 13 cons: SEQUENCE
6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
17:d=2 hl=2 l= 0 prim: NULL
19:d=1 hl=4 l= 271 prim: BIT STRING
0000 - 00 30 82 01 0a 02 82 01-01 00 dd 0a 06 48 b3 4b .0...........H.K
0010 - 80 df 49 82 da 40 ab 1a-28 60 8d 61 2e bd 08 68 ..I..@..(`.a...h
0020 - d7 07 9c 0a cd d0 94 a5-ea 6e 94 f7 da 1a 3d 7a .........n....=z
0030 - 62 2d d8 79 3a c5 12 d6-7c 5a b2 23 8c 0c 1b ae b-.y:...|Z.#....
0040 - 14 75 2e 21 68 5b d1 14-d4 92 e3 fb 41 f8 ff 75 .u.!h[......A..u
0050 - 94 d1 30 75 3f 7d 42 72-34 8f b7 70 a5 43 ed fa ..0u?}Br4..p.C..
0060 - e9 08 64 b0 cb 26 d0 77-78 0f 1d b6 5e 0c 68 ca ..d..&.wx...^.h.
0070 - 44 da 1c 12 2a 99 5f 48-f3 7e b1 c7 36 af ee ff D...*._H.~..6...
0080 - 88 d6 42 5d b6 93 e3 05-f4 2e 29 16 be e4 fc ec ..B]......).....
0090 - 58 06 04 3d de 82 04 6e-a8 7a 59 ee da ff 8e 10 X..=...n.zY.....
00a0 - 7a 17 2f f5 29 f6 e2 3b-ec ba fd f0 c1 3b 0b b0 z./.)..;.....;..
00b0 - 0d c4 ab 0a 86 8c a9 8e-c7 1c 6e 56 89 df dd 5a ..........nV...Z
00c0 - 7b c1 4e a1 2c d1 9c 8f-7f 08 43 0e 22 db 35 9d {.N.,.....C.".5.
00d0 - 9b 53 54 1b 30 64 02 b8-d8 4e 74 5e 88 fc a4 98 .ST.0d...Nt^....
00e0 - 98 0e 74 73 60 46 0a dc-8b c3 2e 22 f6 de 2d f2 ..ts`F....."..-.
00f0 - e0 a9 e7 8d 22 7a b3 32-7f 3f 17 37 09 88 45 2d ...."z.2.?.7..E-
0100 - 6b 6b f1 8e 3c f9 19 30-b6 e5 02 03 01 00 01 kk..<..0.......
(si vous souvenez de nos précédents chapitres sur l'analyse ASN.1 et RSA, vous aurez remarqué à la toute dernière ligne, notre notre petit 0x010001
qui correspond à notre exposant public RSA)
Maintenant que nous avons notre clef publique RSA root.pub
, générons notre dnQualifier à partir d'elle :
openssl base64 -d -in root.pub \
| openssl asn1parse -inform DER -offset 24 -noout -out - \
| openssl sha1 -binary \
| openssl base64
E/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
Maintenant que nous avons notre dnQualifier prêt à l'emploi pour notre OpenSSL, nous pouvons procéder à la création de fichier de configuration OpenSSL avec toutes les informations nécessaires.
Pour des raisons de simplicité pour nous éviter de longues lignes de commandes lors de l'étape de la génération de notre certificat, nous allons créer un fichier de configuration pour OpenSSL - que nous nommerons openssl_root.cfg
:
# cat openssl_root.cfg
[req]
default_md = sha256
default_bits = 2048
distinguished_name = subject
x509_extensions = x509_extensions
utf8 = yes
prompt = no
[subject]
organizationName = DCPINSIDE
organizationalUnitName = DCPINSIDE
commonName = .DCPINSIDE-ROOT
dnQualifier = E/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
[x509_extensions]
basicConstraints = critical, CA:TRUE, pathlen:10
keyUsage = critical, keyCertSign, cRLSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer:always
Si vous avez suivi les précédents chapitres, certains éléments inscrits dans ce fichier de configuration devraient déjà vous parler.
Tout d'abord, nous définissons le message digest (md) à SHA-256 pour les Signatures - c'est notre fameux Signature Algorithm avec son sha256WithRSAEncryption
- et une taille de 2048 bits pour la taille de la clef.
Puis, nous définissons un nom de section pour distinguished_name
qui sont nos attributs dans notre Subject, Issuer et DirName. La valeur subject
est une référence à la section subject
qui va définir chaque Distinguished Names utilisés.
Notre fameux x509_extensions
qui pointe vers la section x509_extensions
et nous retrouvons nos BasicConstraints, KeyUsage, SubjectKeyIdentifier et AuthorityKeyIdentifier que nous avons déjà vu dans le chapitre sur les champs d'un certificat x509.
Rien de surprenant dans tout ceci, nous avons déjà vu tous ces points auparavant.
Pour subjectKeyIdentifier, la valeur hash
indique qu'il va être calculé en suivant le principe vu dans Public Key Thumbprint (plot twist : c'est notre dnQualifier sans son Base64) :
Pour authorityKeyIdentifier, nous spécifions que nous avons besoin de keyId et Issuer (qui sera notre DirName):
# exemple du AuthorityKeyIdentifier de notre futur certificat ;-)
X509v3 Authority Key Identifier:
keyid:13:F2:D1:29:78:82:A8:71:D0:E9:9F:66:CE:56:0A:60:1F:65:C4:C7
DirName:/O=DCPINSIDE/OU=DCPINSIDE/CN=.DCPINSIDE-ROOT/dnQualifier=E\/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
serial:01
keyid
indique qu'il doit copier le SubjectKeyIdentifier de l'Issuer. Dans notre cas, vu que le certificat n'a aucun Issuer (le certificat est auto-signé / self-signed), la valeur sera son propre SubjectKeyIdentifier.
L'option always
indique juste qu'il faut absolument cette valeur. S'il ne peut la récupérer/générer, il doit stopper.
On a défini un pathlen
à 10, mais vous pouvez mettre une autre valeur entre 1 et l'infini sur 64 bits :)
Et enfin, à la fin, nous avons les options utf8
et prompt
, elle spécifie que le certificat utilisera un encodage UTF-8 et qu'avec une désactivation du prompt
, lors de la génération, OpenSSL ne doit pas demander un complément à l'utilisateur (par exemple, il ne demandera pas de passphrase).
A noter que l'option UTF-8 est activé car les normes et le DCI demandent de respecter la RFC 2253 qui se nomme ... Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names.
Ce fichier va nous servir maintenant pour la dernière la dernière étape, la création de notre certificat public !
La création du certificat va nous demander quelques éléments:
openssl_root.cfg
,root.key
qui contient toutes les données utiles RSA Concrètement, ce processus va récupérer les données utiles RSA (notamment modulus et exposant public) pour les insérer dans le certificat public et utiliser la clef privée pour signer le certificat (self-signed).
# sign cert with new Subject and dnQualifier (self-signed, no -CA/-CAkey)
openssl req \
-x509 \
-config "openssl_root.cfg" \
-key "root.key" \
-out "root.crt" \
-set_serial 1 \
-days 365
Avec -config
, nous utilisons notre fameux fichier de config du début - openssl_root.cfg
- c'est lui qui va contrôler toute la fabrication de notre certificat.
Avec -key
, nous indiquons notre fichier d'entrée RSA root.key
contenant toutes les infos utiles pour la création mais surtout pour la signature de notre certificat racine défini dans -out
.
Avec -out
, nous indiquons notre fichier de sortie pour notre certificat x509 DCI au format PEM (on devrait plutôt donner une extension en .pem
mais .crt
- pour certificat - est plus explicite pour l'instant). Ici, notre fichier sera root.crt
Avec -set_serial
, nous définissons un numéro de série, vous pouvez mettre ce que vous voulez tant que cela soit un nombre positif (unsigned int) d'une longueur maximale de 64 bits 2. Si vous ne définissez pas de serial, OpenSSL va en générer un de 160 bits, donc hors norme SMPTE 430-2 - Digital Certificate - Fields Constraints. Notez que nous aurions pu définir un mécanisme de génération de serial dans le fichier de configuration mais l'ajout aurait complexifié inutilement l'ensemble du fichier de configuration et on essaye de faire simple (on essaye... :)
Et enfin, avec -days
, nous définissons une date limite de 365 jours pour notre certificat root (pour de la production, mettez plutôt sur plusieurs années). Il va définir nos champs Validity Not Before et Validity Not After (nous le définissons en ligne de commande car certaines versions d'OpenSSL ne permettent pas de le définir dans le fichier de configuration directement)
Voyons maintenant notre fichier root.crt
fraichement généré :
# openssl x509 -in root.crt -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: O = DCPINSIDE, OU = DCPINSIDE, CN = .DCPINSIDE-ROOT, dnQualifier = E/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
Validity
Not Before: Mar 18 21:58:00 2023 GMT
Not After : Mar 17 21:58:00 2024 GMT
Subject: O = DCPINSIDE, OU = DCPINSIDE, CN = .DCPINSIDE-ROOT, dnQualifier = E/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:dd:0a:06:48:b3:4b:80:df:49:82:da:40:ab:1a:
28:60:8d:61:2e:bd:08:68:d7:07:9c:0a:cd:d0:94:
a5:ea:6e:94:f7:da:1a:3d:7a:62:2d:d8:79:3a:c5:
12:d6:7c:5a:b2:23:8c:0c:1b:ae:14:75:2e:21:68:
5b:d1:14:d4:92:e3:fb:41:f8:ff:75:94:d1:30:75:
3f:7d:42:72:34:8f:b7:70:a5:43:ed:fa:e9:08:64:
b0:cb:26:d0:77:78:0f:1d:b6:5e:0c:68:ca:44:da:
1c:12:2a:99:5f:48:f3:7e:b1:c7:36:af:ee:ff:88:
d6:42:5d:b6:93:e3:05:f4:2e:29:16:be:e4:fc:ec:
58:06:04:3d:de:82:04:6e:a8:7a:59:ee:da:ff:8e:
10:7a:17:2f:f5:29:f6:e2:3b:ec:ba:fd:f0:c1:3b:
0b:b0:0d:c4:ab:0a:86:8c:a9:8e:c7:1c:6e:56:89:
df:dd:5a:7b:c1:4e:a1:2c:d1:9c:8f:7f:08:43:0e:
22:db:35:9d:9b:53:54:1b:30:64:02:b8:d8:4e:74:
5e:88:fc:a4:98:98:0e:74:73:60:46:0a:dc:8b:c3:
2e:22:f6:de:2d:f2:e0:a9:e7:8d:22:7a:b3:32:7f:
3f:17:37:09:88:45:2d:6b:6b:f1:8e:3c:f9:19:30:
b6:e5
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:10
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Subject Key Identifier:
13:F2:D1:29:78:82:A8:71:D0:E9:9F:66:CE:56:0A:60:1F:65:C4:C7
X509v3 Authority Key Identifier:
keyid:13:F2:D1:29:78:82:A8:71:D0:E9:9F:66:CE:56:0A:60:1F:65:C4:C7
DirName:/O=DCPINSIDE/OU=DCPINSIDE/CN=.DCPINSIDE-ROOT/dnQualifier=E\/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
serial:01
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
2a:f3:08:64:3e:49:0f:88:8a:45:9e:54:8f:ec:1c:36:61:e0:
94:a5:00:2e:7f:23:7b:9d:e7:7a:3d:4c:e5:53:cd:b1:5f:53:
9a:a2:d5:94:ed:ac:3c:9a:93:4a:ec:0d:ad:97:b4:94:89:9b:
49:c0:25:d7:6b:6e:8f:ce:23:ab:c5:52:07:3b:d3:c1:23:34:
6b:b3:4f:97:98:8a:59:e9:5c:17:c5:04:8b:91:be:1e:1e:44:
6e:0e:ab:1a:f8:1b:99:a8:04:37:d2:8d:af:96:9d:28:bb:00:
fc:b4:be:af:52:1c:5f:b9:ea:8f:a3:94:41:21:7e:8b:df:6c:
ed:28:e7:df:32:13:1f:da:15:f1:8c:f2:fd:0f:93:e2:32:c1:
88:28:90:9e:7e:51:3b:7b:2e:74:2d:18:2a:f8:92:d0:40:50:
23:b2:44:4d:ca:9f:37:27:5e:5c:0b:ca:59:98:c0:f1:af:7f:
d1:12:41:84:70:27:10:3e:e1:9b:84:59:a2:96:cc:a0:f8:03:
99:f8:01:64:91:e2:a8:2f:93:6f:0d:eb:7f:af:80:f2:46:20:
90:2d:86:f3:c8:16:72:6f:d6:26:4e:04:0c:83:ca:d2:fd:99:
b9:01:5b:a0:b2:32:fe:f5:8b:b7:7b:15:77:32:33:58:d3:3f:
76:1a:86:d9
Nous constatons que nos paramètres sont corrects, notre Subject et Issuer sont identiques, notre dnQualifier est correct.
Nous avons notre BasicConstraint avec un joli CA:TRUE
, un KeyUsage avec nos deux paramètres Certificate Sign
et CRL Sign
, notre Subject Key Identifier se trouve bien dans Authority Key Identifier. Et nos DirName et serial bouclent sur nos Subject et SerialNumber.
Et le tout est correctement signé en SHA256-RSA.
Nous avons enfin notre premier élément, assets/Certificates/samples/dcpinside/root.crt ! Passons maintenant à notre certificat intermédiaire.
Vous verrez que cette partie ressemblera de beaucoup à la précédente : cette génération s'effectuera de la même manière.
Les seules différences notables seront sur un ou deux paramètres, par exemple, son pathlen
qui va être à 0
directement (notez que si vous voulez plusieurs certificats intermédiaires, vous pouvez augmenter ce chiffre, mais il ne doit pas être supérieur à celui de la racine).
Et surtout - le plus important - ce certificat ne sera PAS auto-signé (self-signed), il sera signé par notre certificat racine !
Reprenons nos différentes étapes déjà vu au dessus, cette fois-ci pour notre intermédiaire :
# generate RSA priv/pub keys (2048-bits)
$ openssl genrsa -out "intermediate.key" 2048
# extract public key from intermediate.key
$ openssl rsa -in "intermediate.key" -outform PEM -pubout -out "intermediate.pub"
# get public key thumprint and generate dnqualifier
$ dnqualifier "intermediate.pub"
08lTVeLopfA7fYMpENflCDgNPgY=
Rien de nouveau, on a déjà tout vu précédemment : nous avons maintenant notre fichier intermediate.key
stockant touts les données RSA utiles (clef privé / clef publique) - et intermediate.pub
stockant uniquement sa clef publique.
Voyons notre fichier de configuration OpenSSL openssl_intermediate.cfg
pour notre certificat intermédiaire :
# cat openssl_intermediate.cfg
[req]
default_md = sha256
default_bits = 2048
distinguished_name = subject
x509_extensions = x509_extensions
utf8 = yes
prompt = no
[subject]
organizationName = DCPINSIDE
organizationalUnitName = DCPINSIDE
commonName = .DCPINSIDE-INTERMEDIATE
dnQualifier = 08lTVeLopfA7fYMpENflCDgNPgY=
[x509_extensions]
basicConstraints = critical, CA:TRUE, pathlen:0
keyUsage = critical, keyCertSign, cRLSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer:always
Rien de particulier, le fichier openssl_intermediate.cfg
est quasi le même que celui de notre certificat racine - à ceci près que notre pathlen
est maintenant 0
, et bien évidemment son commonName
qui change.
Passons maintenant à la génération de notre certificat racine à l'aide de nos différents fichiers déjà préparés :
$ openssl req \
-x509 \
-config "openssl_intermediate.cfg" \
-key "intermediate.key" \
-out "intermediate.crt" \
-CA "root.crt" \
-CAkey "root.key" \
-set_serial 1 \
-days 365
Vous remarquez deux options supplémentaires -CA
et -CAkey
. Elles sont très importantes car ce sont elles qui font switcher OpenSSL dans le monde magique de la signature par un autre certificat.
Ces deux options font liens avec le certificat public & la clef de notre issuer. Grâce à ces deux options, nos champs issuers (Issuer et Authority Key Identifier) de notre certificat intermédiaire vont être liés à notre certificat racine.
Le paramètre -CA
va être utile pour OpenSSL pour la récupération des informations du certificat parent stockées dans root.crt
et le paramètre -CAkey
va être utile pour signer ce nouveau certificat à l'aide de la clef privée stockée dans root.key
.
Etudions maintenant notre nouveau fichier certificat intermediate.crt
tout frais :
# openssl x509 -in intermediate.crt -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: O = DCPINSIDE, OU = DCPINSIDE, CN = .DCPINSIDE-ROOT, dnQualifier = E/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
Validity
Not Before: Mar 18 21:58:01 2023 GMT
Not After : Mar 17 21:58:01 2024 GMT
Subject: O = DCPINSIDE, OU = DCPINSIDE, CN = .DCPINSIDE-INTERMEDIATE, dnQualifier = 08lTVeLopfA7fYMpENflCDgNPgY=
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:bb:dd:c7:e8:d2:db:ed:fc:16:25:fd:08:39:68:
4f:14:8f:d7:20:a6:de:29:8e:fc:c4:36:b5:40:f8:
d3:06:99:b1:65:9e:21:ce:40:05:7b:1a:92:ac:3c:
bc:4e:e1:b8:87:80:3b:0b:d5:01:13:83:ec:c7:2f:
cd:13:40:06:52:da:bc:62:7b:12:06:cc:14:1a:01:
13:b7:32:8a:ee:d5:60:16:79:04:65:30:93:bd:79:
26:5a:6f:d9:67:5a:3d:93:9e:07:88:c9:da:c2:15:
b6:58:db:32:f2:3b:a3:6c:f4:73:36:a4:29:c7:3d:
83:a2:64:9f:5d:2e:64:46:5e:7d:a8:92:65:30:62:
35:31:19:56:c5:d7:09:2d:fd:c3:7e:a2:bf:5f:be:
11:ae:19:43:51:1d:5d:76:c0:5e:11:1b:f7:6c:0c:
c2:98:33:ee:e8:17:51:e5:3c:4c:cf:b3:61:08:9f:
bf:40:03:d0:06:c7:83:ac:5f:bf:f0:24:7e:4b:5a:
3f:90:bd:92:2a:5a:af:e7:1d:31:9d:87:3c:95:00:
ff:1c:c7:94:e8:86:57:ac:e9:36:e3:5f:6e:b0:7f:
6a:7f:02:74:ba:a0:73:17:66:2e:02:58:66:d7:5c:
bd:9f:31:b9:08:86:75:c0:8a:94:e1:33:43:9a:7a:
36:bf
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Subject Key Identifier:
D3:C9:53:55:E2:E8:A5:F0:3B:7D:83:29:10:D7:E5:08:38:0D:3E:06
X509v3 Authority Key Identifier:
keyid:13:F2:D1:29:78:82:A8:71:D0:E9:9F:66:CE:56:0A:60:1F:65:C4:C7
DirName:/O=DCPINSIDE/OU=DCPINSIDE/CN=.DCPINSIDE-ROOT/dnQualifier=E\/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
serial:01
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
11:e2:1b:05:92:83:b4:80:ac:14:24:f3:75:b0:d9:b4:d3:29:
fd:da:7f:fb:6d:54:34:a0:43:d8:21:86:1e:ad:b6:11:be:06:
b1:27:64:f1:2e:18:2d:8b:e2:c1:f6:54:00:07:18:27:ff:7f:
65:3b:dc:8f:f7:cf:30:29:84:24:74:33:e6:1a:38:3d:53:b7:
ed:0b:84:66:ec:6f:73:32:c6:ee:7a:25:ff:55:1a:22:c5:c7:
6c:4d:8e:b5:6c:48:78:a8:0a:39:7f:4e:81:58:3f:8d:6f:8e:
ec:c9:24:95:6e:2a:53:d3:5a:a5:e3:47:de:d5:d2:29:de:fe:
c1:82:3c:63:17:db:fc:09:be:24:f3:96:c9:09:30:7f:79:a2:
1f:8b:d5:46:72:08:a2:64:03:ff:53:1a:77:0f:9e:d4:93:1d:
6a:cd:c4:45:5d:23:c2:6f:70:eb:93:3e:a2:cc:01:48:65:8c:
e5:67:07:9d:7c:93:fd:ef:25:78:58:bf:be:f0:ed:28:9c:a3:
3c:42:34:ad:7e:91:02:80:cc:4a:92:86:17:65:35:83:9f:25:
90:26:fa:75:c5:6f:d2:28:54:07:85:09:75:2d:5e:6e:90:e7:
8e:b0:8c:26:c2:56:df:3e:ca:8b:97:46:b3:e5:12:c1:51:1e:
10:1c:ef:64
Nous remarquons que notre Issuer et Authority Key Identifier sont bien liés à notre certificat parent - le certificat racine précédement généré :-)
Voila notre premier certificat intermédiaire ! Passons maintenant à notre dernière étape, notre certificat de fin, notre certificat leaf.
Ce certificat étant en fin de chaîne, il ne fera donc pas partie de l'autorité de certification (CA) et son KeyUsage sera également différent.
Passons maintenant toutes les (mêmes) étapes qu'avant :
# generate RSA priv/pub keys (2048-bits)
$ openssl genrsa -out "leaf.key" 2048
# extract public key from leaf.key
$ openssl rsa -in "leaf.key" -outform PEM -pubout -out "leaf.pub"
# get public key thumprint and generate dnqualifier
dnqualifier leaf.pub
drWstXlPqEsGlWPLJB9+YnIvc4w=
Même chose que précédemment, nous avons maintenant notre fichier leaf.key
stockant touts les données RSA utiles (clef privé / clef publique) - et leaf.pub
stockant uniquement sa clef publique.
Créons maintenant notre fichier de configuration OpenSSL openssl_leaf.cfg
pour notre certificat leaf :
cat openssl_leaf.cfg
[req]
default_md = sha256
default_bits = 2048
distinguished_name = subject
x509_extensions = x509_extensions
utf8 = yes
prompt = no
[subject]
organizationName = DCPINSIDE
organizationalUnitName = DCPINSIDE
commonName = CS.DCPINSIDE-LEAF-ENCODER
dnQualifier = drWstXlPqEsGlWPLJB9+YnIvc4w=
[x509_extensions]
basicConstraints = critical, CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer:always
Notre fichier de configuration OpenSSL pour notre certificat leaf sera quelque peu différent des précédents :
CA:FALSE
: ce certificat ne fait plus partie de l'autorité de certification. Notez également que l'attribut commonName possède en plus un petit CS
qui se balade en tout début de l'attribut, nous définissons son rôle comme Content Signer. Si nous voulions un certificat pour un player, nous aurions placé MD
pour le rôle de Media Decryptor
Et enfin, la génération de notre dernier certificat :
# generate certificate x509 (.crt) with his private key (.key),
# change Subject x509 field with the new dnqualifier
# and signed by authority (-CA/-CAkey)
$ openssl req \
-x509 \
-config "openssl_leaf.cfg" \
-key "leaf.key" \
-out "leaf.crt" \
-CA "intermediate.crt" \
-CAkey "intermediate.key" \
-set_serial 1 \
-days 365
Remarquez maintenant que notre -CA
et -CAkey
est lié à l'intermédiaire, nous utilisons maintenant son parent direct, le certificat public intermediate.crt
et sa clef privée stockée dans intermediate.key
Nous avons maintenant un certificat public leaf stocké dans leaf.crt
Analysons maintenant notre nouveau certificat leaf.crt
:
# openssl x509 -in leaf.crt -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
74:fe:78:97:8e:e3:60:69:82:0b:73:6a:b8:85:24:97:ba:75:b8:4f
Signature Algorithm: sha256WithRSAEncryption
Issuer: O = DCPINSIDE, OU = DCPINSIDE, CN = .DCPINSIDE-INTERMEDIATE, dnQualifier = 08lTVeLopfA7fYMpENflCDgNPgY=
Validity
Not Before: Mar 18 21:58:01 2023 GMT
Not After : Apr 17 21:58:01 2023 GMT
Subject: O = DCPINSIDE, OU = DCPINSIDE, CN = MD.DCPINSIDE-LEAF-ENCODER, dnQualifier = "drWstXlPqEsGlWPLJB9+YnIvc4w="
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:bc:e1:62:cf:cb:9e:a2:6a:42:01:14:b4:8a:71:
dc:90:e3:a9:ad:10:18:42:7d:ed:22:66:6a:8d:2d:
55:60:6a:d8:85:ad:42:31:38:6d:0b:0c:41:f7:9f:
df:64:f4:2c:69:71:ac:5e:74:11:e5:bc:92:ac:5d:
54:28:4b:c5:77:9f:62:41:c0:7c:67:4d:41:a4:45:
24:2b:03:25:93:0c:0b:f1:5e:29:7b:66:22:77:a9:
db:a8:40:80:8e:f4:bb:7a:77:84:79:a0:28:7f:4b:
e9:51:98:4d:24:46:81:4d:1f:fe:53:f5:6f:26:a1:
a2:14:53:31:e0:20:b2:29:06:6b:4d:af:e2:aa:88:
37:78:28:7e:c3:09:40:63:34:cb:4b:ef:e2:4b:44:
f6:9f:8b:65:21:0a:64:ca:f9:af:42:2a:e2:27:45:
e0:28:98:ec:91:62:b7:c5:1c:93:aa:48:17:84:9a:
1d:ae:09:52:ae:d4:2c:9b:52:88:60:56:46:1b:10:
a4:b7:69:00:84:04:dc:04:d7:a4:9d:10:ea:08:00:
b5:65:56:03:60:c9:a3:8f:25:36:f5:94:8a:70:d8:
c5:9d:a0:98:0b:a7:0c:17:d9:68:60:4e:e4:f8:3d:
a3:2c:e2:ac:6b:cb:1a:7b:63:8b:72:f3:94:6c:89:
77:5b
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Subject Key Identifier:
76:B5:AC:B5:79:4F:A8:4B:06:95:63:CB:24:1F:7E:62:72:2F:73:8C
X509v3 Authority Key Identifier:
keyid:D3:C9:53:55:E2:E8:A5:F0:3B:7D:83:29:10:D7:E5:08:38:0D:3E:06
DirName:/O=DCPINSIDE/OU=DCPINSIDE/CN=.DCPINSIDE-ROOT/dnQualifier=E\/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
serial:01
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
54:20:0d:e4:58:1e:d4:e3:65:4c:fa:ce:36:be:a3:29:ad:9c:
6a:2f:eb:6d:52:05:46:b8:54:9b:65:52:23:3b:dd:b2:8b:b8:
b3:90:3b:ad:02:3e:e9:e5:17:fd:af:da:d2:ae:d4:97:69:0b:
3e:e3:2f:85:68:52:11:5b:c7:ce:fc:71:38:76:77:e3:95:68:
54:47:0c:74:7b:7e:6e:87:35:17:3d:2c:8c:ad:96:7a:9a:92:
95:05:82:dd:d2:ce:62:57:a6:9a:1b:35:2d:6d:87:ef:7d:d2:
ae:55:dc:96:d0:66:aa:7b:65:41:8f:60:ac:6c:93:2e:57:f4:
73:c5:ce:8f:2a:d0:c2:b3:e1:62:a4:02:ec:8a:38:00:d9:52:
a6:6c:01:26:7d:b5:e7:9c:aa:5e:43:26:52:18:cc:bf:ab:c5:
e3:49:fa:be:09:be:2e:80:64:3e:05:92:5f:60:5e:03:43:30:
27:1f:09:7e:35:8d:2f:38:97:11:af:d6:84:d5:21:17:2f:f7:
78:f0:90:b5:d0:e2:3c:de:dc:80:28:c5:b7:3b:4d:cb:5c:40:
d5:98:cc:16:bf:56:ee:71:89:6f:50:9a:57:7a:cb:f9:07:ee:
a7:d8:9d:a6:89:29:9a:2b:7a:e9:fe:80:05:4f:44:6a:c2:cf:
f2:e5:00:ac
Constatez également que notre Issuer et Authority Key Identifier sont maintenant liés à notre certificat intermédiaire.
Nous avons maintenant notre premier certificat leaf pour notre usage au quotidien :-)
Pour générer d'autres certificats leaf, il vous suffira de relancer les étapes depuis le début de la section Certificat Leaf.
Et en modifiant le CommonName du Subject, vous pourrez créer d'autres certificats avec différents rôles : Votre arbre va s'agrémenter de nouvelles feuilles supplémentaires (si cela vous est utile).
Voyons rapidement les trois certificats l'un après l'autre :
Notre Certificat Racine :
Issuer : O = DCPINSIDE, OU = DCPINSIDE, CN = .DCPINSIDE-ROOT, dnQualifier = E/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
Subject: O = DCPINSIDE, OU = DCPINSIDE, CN = .DCPINSIDE-ROOT, dnQualifier = E/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
DirName:/O=DCPINSIDE/OU=DCPINSIDE/CN=.DCPINSIDE-ROOT/dnQualifier=E\/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
Notre Certificat Intermédiaire :
Issuer : O = DCPINSIDE, OU = DCPINSIDE, CN = .DCPINSIDE-ROOT, dnQualifier = E/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
Subject: O = DCPINSIDE, OU = DCPINSIDE, CN = .DCPINSIDE-INTERMEDIATE, dnQualifier = 08lTVeLopfA7fYMpENflCDgNPgY=
DirName:/O=DCPINSIDE/OU=DCPINSIDE/CN=.DCPINSIDE-ROOT/dnQualifier=E\/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
Notre Certificat Leaf :
Issuer : O = DCPINSIDE, OU = DCPINSIDE, CN = .DCPINSIDE-INTERMEDIATE, dnQualifier = 08lTVeLopfA7fYMpENflCDgNPgY=
Subject: O = DCPINSIDE, OU = DCPINSIDE, CN = MD.DCPINSIDE-LEAF-ENCODER, dnQualifier = "drWstXlPqEsGlWPLJB9+YnIvc4w="
DirName:/O=DCPINSIDE/OU=DCPINSIDE/CN=.DCPINSIDE-ROOT/dnQualifier=E\/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
Nous constatons que notre Subject du plus bas fait référence à notre Issuer au dessus et ainsi de suite jusqu'au certificat racine. Et notre DirName fait bien mention à l'Issuer au dessus.
Maintenant, avec l'aide d'OpenSSL qui se chargera de vérifier plus en profondeur les certificats, en commençant par la racine :
$ openssl verify \
-show_chain \
-CAfile "root.crt" \
"root.crt"
root.crt: OK
Chain:
depth=0: O = DCPINSIDE, OU = DCPINSIDE, CN = .DCPINSIDE-ROOT, dnQualifier = E/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
Puis l'intermédiaire, nous le validons avec son parent root.crt
:
$ openssl verify \
-show_chain \
-CAfile "root.crt" \
"intermediate.crt"
intermediate.crt: OK
Chain:
depth=0: O = DCPINSIDE, OU = DCPINSIDE, CN = .DCPINSIDE-INTERMEDIATE, dnQualifier = 08lTVeLopfA7fYMpENflCDgNPgY= (untrusted)
depth=1: O = DCPINSIDE, OU = DCPINSIDE, CN = .DCPINSIDE-ROOT, dnQualifier = E/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
Nous constatons notre chaine qui grandit en intégrant notre certificat intermédiaire et notre certificat root dans le bon ordre de profondeur (depth).
Et enfin le certificat leaf :
$ cat "root.crt" "intermediate.crt" > "chain.crt"
$ openssl verify \
-show_chain \
-CAfile "chain.crt" \
"leaf.crt"
encoder.crt: OK
Chain:
depth=0: O = DCPINSIDE, OU = DCPINSIDE, CN = MD.DCPINSIDE-LEAF-ENCODER, dnQualifier = "drWstXlPqEsGlWPLJB9+YnIvc4w=" (untrusted)
depth=1: O = DCPINSIDE, OU = DCPINSIDE, CN = .DCPINSIDE-INTERMEDIATE, dnQualifier = 08lTVeLopfA7fYMpENflCDgNPgY=
depth=2: O = DCPINSIDE, OU = DCPINSIDE, CN = .DCPINSIDE-ROOT, dnQualifier = E/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
Pour la simplicité, nous avons créer une chaîne de certification chain.crt
en concaténant nos deux certificats parents. 3
Si nous n'avions fait simplement qu'une vérification entre le certificat enfant et le certificat parent (certificat leaf et certificat intermédiaire) comme précédemment, OpenSSL n'aura pas pu remonter la chaîne de certification après le certificat intermédiaire vu qu'OpenSSL n'a pas connaissance du certificat racine. Ainsi, en créant un fichier chain.crt
avec nos deux certificats parents, OpenSSL peut valider toute la chaine en une seule fois.
Félicitations, vous venez de générer votre première autorité de certification et votre premier certificat x509 DCI ! :-)
Vous retrouverez certains fichiers utiles ou utilisés pour ce chapitre dans le répertoire assets :
Script shell pour la création d'une chaîne de certification :
-subj
Une chaîne de certification d'exemple qui est utilisé dans ce chapitre, notre version Avec notre Subject dans le fichier de configuration OpenSSL, les dnQualifiers ont été calculés à partir de ces fichiers.
Il n'y a aucune obligation dans la création de ce fichier temporaire. Nous le faisons pour voir étape par étape ce processus. Il est parfaitement possible d'y aller directement sans passer par l'étape de création du fichier .pub
. Avec OpenSSL toujours, il nous suffit de passer directement notre sortie pubout
au format binaire (DER) : ↩
openssl rsa -in root.key -outform DER -pubout -out - 2> /dev/null \
| openssl asn1parse -inform DER -offset 24 -noout -out - \
| openssl sha1 -binary \
| openssl base64
E/LRKXiCqHHQ6Z9mzlYKYB9lxMc=
Le nombre maximum est 18446744073709551615
en décimal - ou 0xffffffffffffffff
en hexadécimal. ↩
normalement, nous devrions utiliser -CAfile
pour le certificat racine et -untrusted
pour chaque certificat intermédiaire. ↩