Certificat x509
Chiffrement asymétrique
Pour comprendre les certificats x509 il est nécessaire de comprendre le chiffrement asymétrique. Rien de tel qu'une image pour comprendre un concept.
Dans cette image on peut voir :
- Si Anne chiffre un document (ensemble de bytes quelconques) avec sa clé privée, elle obtient un nouvel ensemble de bytes (illisible) à savoir, le document chiffré. Toutes les personnes en possession de la clé publique de Anne pourront faire l'opération inverse, déchiffrer le document. On parle dans ce cas d'une signature numérique. En effet, La signature atteste le fait que le document provient bien de Anne. C'est bien Anne qui a fait ce document car seul Anne possède la clé privée qui a pu générer le document chiffrer.
- Si Bob chiffre un document avec la clé publique de Anne, seul Anne pourra déchiffrer ce document car, une fois de plus, elle seule possède la clé privée permettant le déchiffrement.
Certificat x509
Un certificat électronique (aussi appelé certificat numérique ou certificat de clé publique) peut être vu comme une carte d'identité numérique. Il est utilisé principalement pour identifier et authentifier une personne physique ou morale, mais aussi pour chiffrer des échanges.Il est signé par un tiers de confiance qui atteste du lien entre l'identité physique et l'entité numérique (Virtuel).
Détails
Que contient un certificat ? Je vais prendre le mien pour l'exemple. Je le récupère depuis ce site même (druid.es) et je l'enregistre dans le fichier druid.es. Je visualise son contenu grâce à l'utilitaire openssl.
druide@bidouille:~$ openssl x509 -in druid.es -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
35:f3:1e:00:3b:52:bf:35:22:30:41:18:2d:ef:c1:c9
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=FR, ST=Paris, L=Paris, O=Gandi, CN=Gandi Standard SSL CA 2
Validity
Not Before: Apr 28 00:00:00 2014 GMT
Not After : Apr 28 23:59:59 2015 GMT
Subject: OU=Domain Control Validated, OU=Gandi Standard SSL, CN=druid.es
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:95:11:f4:61:35:4f:7f:9e:a3:90:4e:a7:71:5a:
82:96:c3:ba:fa:92:b7:1c:1e:49:aa:9e:98:2e:45:
ee:3b:ca:e5:02:19:ba:bb:6d:e8:a2:94:a9:fd:2a:
f5:94:48:bb:f2:0c:21:47:63:4e:f0:ba:d0:8c:e4:
20:9a:a5:ff:79:da:b6:93:11:74:96:30:b4:e3:ae:
58:88:5f:a7:26:8f:02:8e:01:69:6a:64:d5:49:8a:
f1:ce:3f:7c:6b:fc:8c:45:bb:ec:1c:3c:9b:08:9c:
45:50:0c:86:f1:a6:14:25:bb:d2:ce:98:a0:db:16:
84:f8:4b:f1:a5:05:55:1f:36:f7:7c:41:ef:ac:73:
17:95:e2:92:d6:15:78:b6:0d:d3:23:bd:f9:4c:ce:
31:60:99:57:5c:50:11:b4:4a:c9:8c:0b:0b:48:81:
8b:89:4a:42:28:98:5a:fd:28:ff:b9:0d:11:f1:97:
6f:7e:0d:81:29:d5:aa:5f:1d:64:cc:f3:da:f7:f8:
85:9b:19:ae:04:7f:2a:71:e0:38:cb:26:66:f3:5b:
5c:ba:b6:56:3e:4b:95:57:38:96:d4:b3:24:f7:47:
58:cd:cc:69:c7:92:c6:db:eb:5a:0a:06:c0:61:b0:
52:55:4f:f5:0f:12:6e:af:28:a7:9c:e5:6f:e1:a9:
6f:81
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Authority Key Identifier:
keyid:B3:90:A7:D8:C9:AF:4E:CD:61:3C:9F:7C:AD:5D:7F:41:FD:69:30:EA
X509v3 Subject Key Identifier:
3B:16:27:EE:52:98:00:DB:0C:AA:1B:10:3C:5F:79:D2:C8:10:55:7C
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Certificate Policies:
Policy: 1.3.6.1.4.1.6449.1.2.2.26
CPS: https://cps.usertrust.com
Policy: 2.23.140.1.2.1
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl.usertrust.com/GandiStandardSSLCA2.crl
Authority Information Access:
CA Issuers - URI:http://crt.usertrust.com/GandiStandardSSLCA2.crt
OCSP - URI:http://ocsp.usertrust.com
X509v3 Subject Alternative Name:
DNS:druid.es, DNS:www.druid.es
Signature Algorithm: sha256WithRSAEncryption
2a:f3:7b:b3:fa:76:e3:04:37:f0:e5:82:6b:e9:fa:8e:59:03:
55:68:51:97:dc:69:4e:b9:ce:de:25:e9:2b:b1:0c:41:87:d2:
76:f3:49:07:5c:27:36:b4:4c:55:fe:ec:3b:56:72:41:4e:48:
5e:5d:f5:d0:5f:4c:3d:06:30:ae:69:71:f9:70:ae:1d:2c:42:
36:7d:d4:eb:e3:e9:14:b6:41:03:ad:bf:ee:d3:65:cf:9b:9c:
4f:9d:ad:9f:f6:d0:52:07:5d:24:32:13:ed:d3:2f:5e:ca:c7:
07:77:49:ad:ae:bd:68:29:30:da:79:70:d0:13:7f:d4:54:e2:
5c:b2:bb:81:d5:d6:9a:9a:81:d6:30:f7:71:e0:f4:bd:05:2d:
2c:bc:33:34:38:77:a6:af:43:35:03:cf:6b:22:84:ec:49:5f:
b8:63:69:3b:e7:4b:4d:e8:3e:1f:92:35:b5:85:90:ec:34:c7:
0c:8f:86:31:8d:11:64:1a:03:93:35:f7:79:f6:8f:7f:ac:99:
68:7b:f0:74:dd:6d:08:49:f1:cc:29:0f:5d:7d:18:19:c7:25:
10:f3:6d:cc:c2:29:59:db:1e:3b:a1:7a:bb:b1:58:78:5a:18:
ab:9c:b1:99:61:77:d2:12:6e:3d:2a:52:cc:21:a8:70:9d:50:
b1:48:ab:57
- Subject: OU=Domain Control Validated, OU=Gandi Standard SSL, CN=druid.es indique le nom du propriétaire, celui pour qui le certificat a été délivré
- Issuer: C=FR, ST=Paris, L=Paris, O=Gandi, CN=Gandi Standard SSL CA 2 indique l'autorité qui a délivré le certificat à Subject
- Signature Algorithm: sha256WithRSAEncryption indique que Issuer, pour valider le certificat, a prit une partie de ce certificat, qu'il en a crée un hash sha256 qu'il a ensuite signé avec sa clé privée. Cette signature se trouve plus bas dans le certificat. Si je possède la clé publique de Issuer, je pourrai faire le déchiffrement de cette signature pour retrouver le sha256
- On trouve ensuite la clé publique de Subject
Modulus: 00:95:11:f4:61:35:4f:7f:9e:a3:90:4e:a7:71:5a: 82:96:c3: etc...
- On trouve encore la signature au bas du certificat
Signature Algorithm: sha256WithRSAEncryption 2a:f3:7b:b3:fa:76:e3:04:37:f0:e5:82:6b:e9:fa:8e:59:03: 55:68:51:97:dc:69:4e:b9:ce:de:25:e9:2b:b1: etc...
C'est bien la question que se pose un navigateur web quand il télécharge un certificat.
Validation
Pour valider un certificat il faut:
- Extraire la signature du certificat
- Trouver la clé publique de Issuer
- Connaître les parties du certificat utilisées pour générer le hash sha256
- Générer notre propre hash avec le certificat téléchargé
- Déchiffrer la signature pour obtenir le hash
- Comparer les deux hash. Celui qu'on a générer avec ce certificat et celui que Issuer a généré et placer dans la signature
druide@bidouille:~$ openssl asn1parse -in druid.es
0:d=0 hl=4 l=1255 cons: SEQUENCE
4:d=1 hl=4 l= 975 cons: SEQUENCE
8:d=2 hl=2 l= 3 cons: cont [ 0 ]
10:d=3 hl=2 l= 1 prim: INTEGER :02
13:d=2 hl=2 l= 16 prim: INTEGER :35F31E003B52BF35223041182DEFC1C9
31:d=2 hl=2 l= 13 cons: SEQUENCE
... ETC...
985:d=2 hl=2 l= 9 prim: OBJECT :sha256WithRSAEncryption
996:d=2 hl=2 l= 0 prim: NULL
998:d=1 hl=4 l= 257 prim: BIT STRING
La signature correspond au dernier objet de cette liste. On peut l'extraire dans le fichier signature ainsi
## extraction
druide@bidouille:~$ openssl asn1parse -in druid.es -out signature -noout -strparse 998
## visualisation
druide@bidouille:~$ hd signature
00000000 2a f3 7b b3 fa 76 e3 04 37 f0 e5 82 6b e9 fa 8e |*.{..v..7...k...|
00000010 59 03 55 68 51 97 dc 69 4e b9 ce de 25 e9 2b b1 |Y.UhQ..iN...%.+.|
00000020 0c 41 87 d2 76 f3 49 07 5c 27 36 b4 4c 55 fe ec |.A..v.I.\'6.LU..|
00000030 3b 56 72 41 4e 48 5e 5d f5 d0 5f 4c 3d 06 30 ae |;VrANH^].._L=.0.|
00000040 69 71 f9 70 ae 1d 2c 42 36 7d d4 eb e3 e9 14 b6 |iq.p..,B6}......|
00000050 41 03 ad bf ee d3 65 cf 9b 9c 4f 9d ad 9f f6 d0 |A.....e...O.....|
00000060 52 07 5d 24 32 13 ed d3 2f 5e ca c7 07 77 49 ad |R.]$2.../^...wI.|
00000070 ae bd 68 29 30 da 79 70 d0 13 7f d4 54 e2 5c b2 |..h)0.yp....T.\.|
00000080 bb 81 d5 d6 9a 9a 81 d6 30 f7 71 e0 f4 bd 05 2d |........0.q....-|
00000090 2c bc 33 34 38 77 a6 af 43 35 03 cf 6b 22 84 ec |,.348w..C5..k"..|
000000a0 49 5f b8 63 69 3b e7 4b 4d e8 3e 1f 92 35 b5 85 |I_.ci;.KM.>..5..|
000000b0 90 ec 34 c7 0c 8f 86 31 8d 11 64 1a 03 93 35 f7 |..4....1..d...5.|
000000c0 79 f6 8f 7f ac 99 68 7b f0 74 dd 6d 08 49 f1 cc |y.....h{.t.m.I..|
000000d0 29 0f 5d 7d 18 19 c7 25 10 f3 6d cc c2 29 59 db |).]}...%..m..)Y.|
000000e0 1e 3b a1 7a bb b1 58 78 5a 18 ab 9c b1 99 61 77 |.;.z..XxZ.....aw|
000000f0 d2 12 6e 3d 2a 52 cc 21 a8 70 9d 50 b1 48 ab 57 |..n=*R.!.p.P.H.W|
00000100
Pour déchiffrer cette signature, j'ai besoin de la clé publique de Issuer et donc de son certificat. Je pourrais allé chercher dans la banque des certificats du navigateur, en effet, les navigateurs possèdent une grande quantité de certificats en interne mais pour ce cas, celui de Gandi n'y figure pas.
##Top Level
Issuer: C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network, OU=http://www.usertrust.com, CN=UTN - DATACorp SGC
Subject: C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network, OU=http://www.usertrust.com, CN=UTN - DATACorp SGC
Issuer: C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network, OU=http://www.usertrust.com, CN=UTN - DATACorp SGC
Subject: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
Subject: C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority
Issuer: C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority
Subject: C=FR, ST=Paris, L=Paris, O=Gandi, CN=Gandi Standard SSL CA 2
Issuer: C=FR, ST=Paris, L=Paris, O=Gandi, CN=Gandi Standard SSL CA 2
Subject: OU=Domain Control Validated, OU=Gandi Standard SSL, CN=druid.es
On a donc dans l'ordre, druid.es -> Gandi Standard SSL CA 2 -> USERTrust RSA Certification Authority -> UTN - DATACorp SGC -> UTN - DATACorp SGC (Root CA)
Pour obtenir le certificat de Gandi, on peut le télécharger chez Gandi ou le récupérer lors de la connexion à druid.es. Par exemple avec wireshark. Il suffit de le sélectionner et de l'exporter.
druide@bidouille:~$ openssl x509 -in GandiCertificat.pem -pubkey -noout > GandiPub.key
Maintenant, avec la clé publique de Gandi, on peut examiner la signature
druide@bidouille:~$ openssl rsautl -verify -in signature -inkey GandiPub.key -pubin -asn1parse
0:d=0 hl=2 l= 49 cons: SEQUENCE
2:d=1 hl=2 l= 13 cons: SEQUENCE
4:d=2 hl=2 l= 9 prim: OBJECT :sha256
15:d=2 hl=2 l= 0 prim: NULL
17:d=1 hl=2 l= 32 prim: OCTET STRING
0000 - 8b d2 e1 fa 59 ea 18 72-5d af 6e 63 a0 7f 69 57 ....Y..r].nc..iW
0010 - 36 1e 82 67 7f d2 19 2c-f1 6d 1d f7 cb db 27 4f 6..g...,.m....'O
On y trouve le sha256 ainsi que l'information de ce qui a été utilisé pour générer le sha256, en l'occurrence la partie du certificat de druid.es utilisée pour générer le sha256. On peut extraire cette partie du certificat dans le fichier tbs ainsi
druide@bidouille:~$ openssl asn1parse -in druid.es -out tbs -noout -strparse 4
druide@bidouille:~$ hd tbs
00000000 30 82 03 cf a0 03 02 01 02 02 10 35 f3 1e 00 3b |0..........5...;|
00000010 52 bf 35 22 30 41 18 2d ef c1 c9 30 0d 06 09 2a |R.5"0A.-...0...*|
00000020 86 48 86 f7 0d 01 01 0b 05 00 30 5f 31 0b 30 09 |.H........0_1.0.|
00000030 06 03 55 04 06 13 02 46 52 31 0e 30 0c 06 03 55 |..U....FR1.0...U|
00000040 04 08 13 05 50 61 72 69 73 31 0e 30 0c 06 03 55 |....Paris1.0...U|
00000050 04 07 13 05 50 61 72 69 73 31 0e 30 0c 06 03 55 |....Paris1.0...U|
00000060 04 0a 13 05 47 61 6e 64 69 31 20 30 1e 06 03 55 |....Gandi1 0...U|
00000070 04 03 13 17 47 61 6e 64 69 20 53 74 61 6e 64 61 |....Gandi Standa|
00000080 72 64 20 53 53 4c 20 43 41 20 32 30 1e 17 0d 31 |rd SSL CA 20...1|
00000090 34 30 34 32 38 30 30 30 30 30 30 5a 17 0d 31 35 |40428000000Z..15|
000000a0 30 34 32 38 32 33 35 39 35 39 5a 30 53 31 21 30 |0428235959Z0S1!0|
000000b0 1f 06 03 55 04 0b 13 18 44 6f 6d 61 69 6e 20 43 |...U....Domain C|
000000c0 6f 6e 74 72 6f 6c 20 56 61 6c 69 64 61 74 65 64 |ontrol Validated|
000000d0 31 1b 30 19 06 03 55 04 0b 13 12 47 61 6e 64 69 |1.0...U....Gandi|
000000e0 20 53 74 61 6e 64 61 72 64 20 53 53 4c 31 11 30 | Standard SSL1.0|
000000f0 0f 06 03 55 04 03 13 08 64 72 75 69 64 2e 65 73 |...U....druid.es|
00000100 30 82 01 22 30 0d 06 09 2a 86 48 86 f7 0d 01 01 |0.."0...*.H.....|
00000110 01 05 00 03 82 01 0f 00 30 82 01 0a 02 82 01 01 |........0.......|
00000120 00 95 11 f4 61 35 4f 7f 9e a3 90 4e a7 71 5a 82 |....a5O....N.qZ.|
00000130 96 c3 ba fa 92 b7 1c 1e 49 aa 9e 98 2e 45 ee 3b |........I....E.;|
00000140 ca e5 02 19 ba bb 6d e8 a2 94 a9 fd 2a f5 94 48 |......m.....*..H|
00000150 bb f2 0c 21 47 63 4e f0 ba d0 8c e4 20 9a a5 ff |...!GcN..... ...|
00000160 79 da b6 93 11 74 96 30 b4 e3 ae 58 88 5f a7 26 |y....t.0...X._.&|
00000170 8f 02 8e 01 69 6a 64 d5 49 8a f1 ce 3f 7c 6b fc |....ijd.I...?|k.|
00000180 8c 45 bb ec 1c 3c 9b 08 9c 45 50 0c 86 f1 a6 14 |.E...K.W8...$.|
00000200 47 58 cd cc 69 c7 92 c6 db eb 5a 0a 06 c0 61 b0 |GX..i.....Z...a.|
00000210 52 55 4f f5 0f 12 6e af 28 a7 9c e5 6f e1 a9 6f |RUO...n.(...o..o|
00000220 81 02 03 01 00 01 a3 82 01 a9 30 82 01 a5 30 1f |..........0...0.|
00000230 06 03 55 1d 23 04 18 30 16 80 14 b3 90 a7 d8 c9 |..U.#..0........|
00000240 af 4e cd 61 3c 9f 7c ad 5d 7f 41 fd 69 30 ea 30 |.N.a
On peut finalement recrée un sha256 en se basant sur ce contenu. Si le sha256 est le même que celui contenu dans la signature, alors le certificat druid.es présent sur le site est exactement le même que celui que Gandi a validé
druide@bidouille:~$ openssl sha256 -c tbs
SHA256(tbs)= 8b:d2:e1:fa:59:ea:18:72:5d:af:6e:63:a0:7f:69:57:36:1e:82:67:7f:d2:19:2c:f1:6d:1d:f7:cb:db:27:4f
On voit que ce sha256 et le même que celui contenu dans la signature. On peut donc dire que le certificat que Gandi à authentifié, et le même que celui reçu en allant sur druid.es