{"id":2559,"date":"2021-07-31T09:02:00","date_gmt":"2021-07-31T07:02:00","guid":{"rendered":"http:\/\/blogperso.union31.fr\/?p=2559"},"modified":"2021-11-21T17:13:52","modified_gmt":"2021-11-21T16:13:52","slug":"qr-code","status":"publish","type":"post","link":"https:\/\/blogperso.union31.fr\/?p=2559","title":{"rendered":"QR-Code pass sanitaire &#8230;"},"content":{"rendered":"\n<p>L&rsquo;objectif est de voir pas \u00e0 pas comment sont stock\u00e9es et quelles donn\u00e9es sont pr\u00e9sentes dans un QR-CODE d\u00e9di\u00e9 au passe sanitaire.<\/p>\n\n\n\n<p>Pour cela nous utiliserons une plateforme Linux et lancerons quelques commandes Shell afin de voir toutes les \u00e9tapes et structures qui sont incluses dans le QR-Code.<\/p>\n\n\n\n<p>Toutes les r\u00e9f\u00e9rences seront indiqu\u00e9es au fur et \u00e0 mesure quelles soit techniques (norme RFC, IETF, etc.) ou descriptives (documents europ\u00e9ens dans la plupart des cas).<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Sommaire<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#I_Ressources_initiales\" >I Ressources initiales<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#I1_Quelques_liens\" >I.1 Quelques liens<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#I2_Outils\" >I.2 Outils :<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#II_Recuperer_les_informations_binaires_dun_QR-CODE\" >II R\u00e9cup\u00e9rer les informations binaires d&rsquo;un QR-CODE<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#II1_De_limage_a_la_donnee_binaire\" >II.1 De l&rsquo;image \u00e0 la donn\u00e9e binaire<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#II2_Premiere_structure_de_donnees\" >II.2 Premi\u00e8re structure de donn\u00e9es<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#II3_Du_binaire_a_la_donnees_utiles\" >II.3 Du binaire \u00e0 la donn\u00e9es utiles<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#II31_Logique_de_la_structure_des_donnees\" >II.3.1 Logique de la structure des donn\u00e9es<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#II32_Recuperation_de_lobjet_%C2%AB_COSE_%C2%BB\" >II.3.2 R\u00e9cup\u00e9ration de l&rsquo;objet \u00ab\u00a0COSE\u00a0\u00bb<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#II33_Analyse_de_lobjet_COSE\" >II.3.3 Analyse de l&rsquo;objet COSE<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#III_Lecture_de_lobjet_CBOR_donnees_utiles_concernant_le_pass_sanitaire\" >III Lecture de l&rsquo;objet CBOR (donn\u00e9es utiles concernant le pass sanitaire)<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#III1_Donnees_binaires_du_CBOR\" >III.1 Donn\u00e9es binaires du CBOR<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#III2_Decodage_du_CBOR\" >III.2 D\u00e9codage du CBOR<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#III3_Les_donnees_utiles_dans_le_CBOR\" >III.3 Les donn\u00e9es utiles dans le CBOR<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#IV_Avec_un_QR-CODE_dun_vrai_passe_sanitaire%E2%80%A6\" >IV Avec un QR-CODE d&rsquo;un vrai passe sanitaire&#8230;<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#V_Verification_du_QR-CODE\" >V V\u00e9rification du QR-CODE<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#V1_Introduction\" >V.1 Introduction<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#V2_Recuperation_de_la_clef_publique\" >V.2 R\u00e9cup\u00e9ration de la clef publique<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#V21_Partie_entete_recuperation_du_Key_Identifier_Kid\" >V.2.1 Partie ent\u00eate : r\u00e9cup\u00e9ration du Key Identifier (Kid)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#V22_Clef_publique\" >V.2.2 Clef publique<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-21\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#V221_Recuperation_de_la_clef_publique\" >V.2.2.1 R\u00e9cup\u00e9ration de la clef publique<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-22\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#V222_Creation_du_fichier_de_la_clef_publique\" >V.2.2.2 Cr\u00e9ation du fichier de la clef publique<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-23\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#V3_Recuperation_et_traitement_de_la_signature_du_QR-CODE\" >V.3 R\u00e9cup\u00e9ration et traitement de la signature du QR-CODE<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-24\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#V31_Avant_de_commencer\" >V.3.1 Avant de commencer<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-25\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#V32_Creation_dun_fichier_de_signature_lisible_par_Openssl_format_DER\" >V.3.2 Cr\u00e9ation d&rsquo;un fichier de signature lisible par Openssl (format DER)<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-26\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#V4_Donnees_a_valider\" >V.4 Donn\u00e9es \u00e0 valider<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-27\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#V5_Verification_avec_OpenSSL\" >V.5 V\u00e9rification (avec OpenSSL)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-28\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#V6_Ressources\" >V.6 Ressources<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-29\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#VI_Fin\" >VI Fin<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-30\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#VI1_Constat_simple\" >VI.1 Constat simple<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-31\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#VI2_Modification_du_JSON_et_creation_dun_autre_QR-Code\" >VI.2 Modification du JSON et cr\u00e9ation d&rsquo;un autre QR-Code<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-32\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#VI3_Mais_peut-on_creer_un_vraifaux_QR-CODE\" >VI.3 Mais peut-on cr\u00e9er un vrai\/faux QR-CODE ?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-33\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#VI4_Donnees_en_clair_pas_chiffrees\" >VI.4 Donn\u00e9es en clair, pas chiffr\u00e9es ?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-34\" href=\"https:\/\/blogperso.union31.fr\/?p=2559\/#VI5_Lapplication_%C2%AB_TousAntiCovid_verif_%C2%BB\" >VI.5 L&rsquo;application \u00ab\u00a0TousAntiCovid verif\u00a0\u00bb<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"I_Ressources_initiales\"><\/span>I Ressources initiales<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"I1_Quelques_liens\"><\/span>I.1 Quelques liens<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Liens pour comprendre :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>documentation europ\u00e9enne : <a rel=\"noreferrer noopener\" href=\"https:\/\/ec.europa.eu\/health\/ehealth\/covid-19_fr\" target=\"_blank\">https:\/\/ec.europa.eu\/health\/ehealth\/covid-19_fr<\/a><\/li><li>explication g\u00e9n\u00e9rale : <ul><li><a rel=\"noreferrer noopener\" href=\"https:\/\/blog.callicode.fr\/post\/2021\/covid_pass.html\" target=\"_blank\">https:\/\/blog.callicode.fr\/post\/2021\/covid_pass.html<\/a> (en fran\u00e7ais) ;<\/li><\/ul><ul><li><a rel=\"noreferrer noopener\" href=\"https:\/\/gir.st\/blog\/greenpass.html\" target=\"_blank\">https:\/\/gir.st\/blog\/greenpass.html<\/a> ;<\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/harrisonsand.com\/posts\/covid-certificates\/\" target=\"_blank\">https:\/\/harrisonsand.com\/posts\/covid-certificates\/<\/a> ;<\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/www.bortzmeyer.org\/7049.html\" target=\"_blank\">https:\/\/www.bortzmeyer.org\/7049.html <\/a>lire un objet binaire CBOR (en fran\u00e7ais) ;<\/li><\/ul><\/li><li>obtenir des QR-Code de test : <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/eu-digital-green-certificates\/dgc-testdata\" target=\"_blank\">https:\/\/github.com\/eu-digital-green-certificates\/dgc-testdata<\/a> ;<\/li><li>autres :<ul><li>les diff\u00e9rents type de codes barre : <a rel=\"noreferrer noopener\" href=\"https:\/\/fr.wikipedia.org\/wiki\/Liste_des_symbologies\" target=\"_blank\">https:\/\/fr.wikipedia.org\/wiki\/Liste_des_symbologies<\/a> ;<\/li><li>un lecteur de CBOR on line (texte vers Objet CBOR) : <a rel=\"noreferrer noopener\" href=\"http:\/\/www.cbor.me\/\" target=\"_blank\">http:\/\/www.cbor.me\/<\/a>.<\/li><\/ul><\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"I2_Outils\"><\/span>I.2 Outils :<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Quelques outils qui seront utilis\u00e9s (avec Linux Ubuntu LTS 20.04) :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">sudo apt install zbar-tools  #permet de scanner un qr-code et d'en sortir du texte      \nsudo apt install zlib1g #librairie zlib pour d\u00e9compresser\nsudo apt install qpdf # outil qui int\u00e8gre zlib et utilisable en ligne de commande\nsudo apt install qrencode  # g\u00e9n\u00e9rer l'image d'un qr-code<\/code><\/pre>\n\n\n\n<p>Lien pour r\u00e9cup\u00e9rer les sources d&rsquo;un d\u00e9codeur base45 : <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/ehn-dcc-development\/base45-ansi-C\" target=\"_blank\">https:\/\/github.com\/ehn-dcc-development\/base45-ansi-C<\/a><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\"># outils pour la compiltation\nsudo apt-get install build-essential\n\n# cr\u00e9ation du r\u00e9pertoire qui va recevoir le code source\nmkdir base45\n\n# r\u00e9cup\u00e9ration du code source\ngit clone https:\/\/github.com\/ehn-dcc-development\/base45-ansi-C.git --depth 1 --branch=main .\/base45\/\n\n# compilation des sources\ncd .\/base45\nsudo make\n\n# copie de l'executable dans \/bin pour qu'il soit accessible de tous...\nsudo cp base45 \/bin\/base45\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"II_Recuperer_les_informations_binaires_dun_QR-CODE\"><\/span>II R\u00e9cup\u00e9rer les informations binaires d&rsquo;un QR-CODE<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"II1_De_limage_a_la_donnee_binaire\"><\/span>II.1 De l&rsquo;image \u00e0 la donn\u00e9e binaire<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Structure des donn\u00e9es d&rsquo;un QR-Code pour le pass sanitaire :<\/p>\n\n\n\n<p>Les sp\u00e9cifications qui r\u00e9gissent comment sont stock\u00e9es les donn\u00e9es ou lurs structures se trouvent dans le document suivant : <a rel=\"noreferrer noopener\" href=\"https:\/\/ec.europa.eu\/health\/sites\/default\/files\/ehealth\/docs\/digital-green-certificates_v3_en.pdf\" target=\"_blank\">Technical Specifications for Digital Green Certificates Volume 3<\/a>. Ce document parmi d&rsquo;autres sont tous regroup\u00e9s dans la page suivante : <a rel=\"noreferrer noopener\" href=\"https:\/\/ec.europa.eu\/health\/ehealth\/covid-19_fr\" target=\"_blank\"><strong>https:\/\/ec.europa.eu\/health\/ehealth\/covid-19_fr<\/strong><\/a>.<\/p>\n\n\n\n<p>Voici le QR-Code de test sur lequel nous allons travailler :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/11\/qr_image.jpg\" alt=\"\" class=\"wp-image-2947\" width=\"281\" height=\"281\" srcset=\"https:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/11\/qr_image.jpg 904w, https:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/11\/qr_image-300x300.jpg 300w, https:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/11\/qr_image-150x150.jpg 150w, https:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/11\/qr_image-768x768.jpg 768w, https:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/11\/qr_image-270x270.jpg 270w, https:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/11\/qr_image-230x230.jpg 230w\" sizes=\"auto, (max-width: 281px) 100vw, 281px\" \/><\/figure>\n\n\n\n<p>La premi\u00e8re op\u00e9ration consiste \u00e0 r\u00e9cup\u00e9rer l&rsquo;information brute contenue dans le QR-Code. En Shell elle s&rsquo;obtient de la mani\u00e8re suivante :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">zbarimg --raw --quiet qr_image.jpg | xxd # --raw : mode brut, cela permet d'enlever le type de code barre (ici un qr-code) afficher par d\u00e9faut pour cette commande\n<\/code><\/pre>\n\n\n\n<p>ce qui donne :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">00000000: <span class=\"has-inline-color has-vivid-red-color\">4843 313a 4e<\/span><span class=\"has-inline-color has-vivid-purple-color\">43 463a 3630 3341 3054 3957  <\/span><span class=\"has-inline-color has-vivid-red-color\">HC1:<\/span><span class=\"has-inline-color has-vivid-purple-color\">NCF:603A0T9W\n00000010: 5457 4753 4c4b 4320 344b 3639 3457 4a4e  TWGSLKC 4K694WJN\n00000020: 2e30 4a24 3643 2d37 5741 4230 584b 334a  .0J$6C-7WAB0XK3J\n00000030: 4353 4741 3246 3352 3850 5034 5632 4633  CSGA2F3R8PP4V2F3\n00000040: 3556 5050 2e45 5935 302e 464b 385a 4b4f  5VPP.EY50.FK8ZKO\n00000050: 2f45 5a4b 455a 3936 4c46 362f 4136 2e2e  \/EZKEZ96LF6\/A6..\n00000060: 4456 2544 5a4a 4330 2f44 3555 4120 5145  DV%DZJC0\/D5UA QE\n00000070: 4c50 4347 2f44 5955 4348 5938 3355 4147  LPCG\/DYUCHY83UAG\n00000080: 5643 2a4a 434e 4636 4634 3633 5735 4b46  VC*JCNF6F463W5KF\n00000090: 3656 4636 4945 4353 4847 344b 4344 3344  6VF6IECSHG4KCD3D\n000000a0: 5834 3742 3436 494c 3636 3436 482a 364d  X47B46IL6646H*6M\n000000b0: 5745 574a 4441 3641 3a39 3631 4136 5134  WEWJDA6A:961A6Q4\n000000c0: 3745 4d36 4224 4446 4f43 3052 3633 4b43  7EM6B$DFOC0R63KC\n000000d0: 5a50 434e 4636 4f46 3633 5735 2451 362b  ZPCNF6OF63W5$Q6+\n000000e0: 3936 2f53 4135 5236 4e46 3631 4737 3335  96\/SA5R6NF61G735\n000000f0: 3634 4b43 2a4b 4554 4636 4134 362e 3936  64KC*KETF6A46.96\n00000100: 3634 3642 3536 3557 4543 2e44 3124 434b  646B565WEC.D1$CK\n00000110: 5745 445a 4336 5643 5334 3436 2443 3457  WEDZC6VCS446$C4W\n00000120: 4555 5043 334a 4355 4941 2b45 4424 2e45  EUPC3JCUIA+ED$.E\n00000130: 4624 444d 5745 3824 4342 4a45 4d56 4342  F$DMWE8$CBJEMVCB\n00000140: 3434 3524 4342 5745 522e 4347 5043 3457  445$CBWER.CGPC4W\n00000150: 454f 5043 4538 4648 5a41 312b 394c 5a41  EOPCE8FHZA1+9LZA\n00000160: 5a4d 3831 4737 3241 3632 2b38 4f47 374a  ZM81G72A62+8OG7J\n00000170: 3039 5534 3741 4238 5635 3954 2536 5a48  09U47AB8V59T%6ZH\n00000180: 424f 3537 5834 3852 5549 5930 3358 514f  BO57X48RUIY03XQO\n00000190: 4b2a 465a 554e 4d20 5546 5934 4435 4320  K*FZUNM UFY4D5C \n000001a0: 5333 5239 5557 2d32 522a 344b 5a4a 5435  S3R9UW-2R*4KZJT5\n000001b0: 4d20 4d49 4d3a 3033 524d 5a4e 4120 4c4b  M MIM:03RMZNA LK\n000001c0: 544f 3334 5041 2e48 3531 3936 3650 5330  TO34PA.H51966PS0\n000001d0: 4b41 502d 4b4c 5048 2e51 3624 4b53 544a  KAP-KLPH.Q6$KSTJ\n000001e0: 302d 4736 3538 524c 3548 5231 0a         0-G658RL5HR1.<\/span>\n<\/code><\/pre>\n\n\n\n<p>A ce stade nous avons l&rsquo;int\u00e9gralit\u00e9 des donn\u00e9es binaires de l&rsquo;image QR-Code. <\/p>\n\n\n\n<p>A titre d&rsquo;informations, pour r\u00e9cup\u00e9rer les donn\u00e9es binaires dans une simple chaine de caract\u00e8res :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">zbarimg --raw --quiet qr_image.jpg | <span class=\"has-inline-color has-vivid-cyan-blue-color\">xxd -p -c 1000<\/span>   # affiche les donn\u00e9es binaires par bloc de 1000 octets<\/code><\/pre>\n\n\n\n<p>ce qui donne :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">4843313a4e43463a3630334130543957545747534c4b4320344b363934574a4e2e304a2436432d3757414230584b334a43534741324633523850503456324633355650502e455935302e464b385a4b4f2f455a4b455a39364c46362f41362e2e445625445a4a43302f443555412051454c5043472f445955434859383355414756432a4a434e46364634363357354b4636564636494543534847344b43443344583437423436494c36363436482a364d5745574a444136413a3936314136513437454d36422444464f43305236334b435a50434e46364f46363357352451362b39362f53413552364e4636314737333536344b432a4b455446364134362e3936363436423536355745432e443124434b5745445a43365643533434362443345745555043334a435549412b4544242e454624444d5745382443424a454d5643423434352443425745522e434750433457454f5043453846485a41312b394c5a415a4d38314737324136322b384f47374a30395534374142385635395425365a48424f353758343852554959303358514f4b2a465a554e4d2055465934443543205333523955572d32522a344b5a4a54354d204d494d3a3033524d5a4e41204c4b544f333450412e4835313936365053304b41502d4b4c50482e5136244b53544a302d47363538524c354852310a<\/code><\/pre>\n\n\n\n<p>et inversement :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">echo \"4843313a4e43463a3630334130543957545747534c4b4320344b363934574a4e2e304a2436432d3757414230584b334a43534741324633523850503456324633355650502e455935302e464b385a4b4f2f455a4b455a39364c46362f41362e2e445625445a4a43302f443555412051454c5043472f445955434859383355414756432a4a434e46364634363357354b4636564636494543534847344b43443344583437423436494c36363436482a364d5745574a444136413a3936314136513437454d36422444464f43305236334b435a50434e46364f46363357352451362b39362f53413552364e4636314737333536344b432a4b455446364134362e3936363436423536355745432e443124434b5745445a43365643533434362443345745555043334a435549412b4544242e454624444d5745382443424a454d5643423434352443425745522e434750433457454f5043453846485a41312b394c5a415a4d38314737324136322b384f47374a30395534374142385635395425365a48424f353758343852554959303358514f4b2a465a554e4d2055465934443543205333523955572d32522a344b5a4a54354d204d494d3a3033524d5a4e41204c4b544f333450412e4835313936365053304b41502d4b4c50482e5136244b53544a302d47363538524c354852310a\" |<span class=\"has-inline-color has-vivid-cyan-blue-color\"> xxd -r -p<\/span><\/code><\/pre>\n\n\n\n<p>ce qui donne :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">HC1:NCF:603A0T9WTWGSLKC 4K694WJN.0J$6C-7WAB0XK3JCSGA2F3R8PP4V2F35VPP.EY50.FK8ZKO\/EZKEZ96LF6\/A6..DV%DZJC0\/D5UA QELPCG\/DYUCHY83UAGVC*JCNF6F463W5KF6VF6IECSHG4KCD3DX47B46IL6646H*6MWEWJDA6A:961A6Q47EM6B$DFOC0R63KCZPCNF6OF63W5$Q6+96\/SA5R6NF61G73564KC*KETF6A46.96646B565WEC.D1$CKWEDZC6VCS446$C4WEUPC3JCUIA+ED$.EF$DMWE8$CBJEMVCB445$CBWER.CGPC4WEOPCE8FHZA1+9LZAZM81G72A62+8OG7J09U47AB8V59T%6ZHBO57X48RUIY03XQOK*FZUNM UFY4D5C S3R9UW-2R*4KZJT5M MIM:03RMZNA LKTO34PA.H51966PS0KAP-KLPH.Q6$KSTJ0-G658RL5HR1<\/code><\/pre>\n\n\n\n<p>A ce stade nous avons donc r\u00e9cup\u00e9r\u00e9 les donn\u00e9es brutes. Nous allons voir comment elles sont structur\u00e9es. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"II2_Premiere_structure_de_donnees\"><\/span>II.2 Premi\u00e8re structure de donn\u00e9es<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Apr\u00e8s avoir retir\u00e9 les informations binaires du QR-Code, nous obtenons la structure est la suivante:<\/p>\n\n\n\n<p>[<strong><span class=\"has-inline-color has-vivid-red-color\">version<\/span><\/strong>][<span class=\"has-inline-color has-vivid-purple-color\">donn\u00e9es<\/span>]<\/p>\n\n\n\n<p>La version est une donn\u00e9e en clair. Elle permet d&rsquo;identifier la version du pass sanitaire. A ce jour il existe 2 versions (<a href=\"https:\/\/ec.europa.eu\/health\/sites\/default\/files\/ehealth\/docs\/digital-green-certificates_v3_en.pdf\" target=\"_blank\" rel=\"noreferrer noopener\">page 6  du document europ\u00e9en<\/a>)<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>HC1 : Health Certificate 1<\/li><li>HC2 : Health Certificate 2<\/li><\/ul>\n\n\n\n<p>Aujourd&rsquo;hui c&rsquo;est la version \u00ab\u00a0HC1\u00a0\u00bb qui est utilis\u00e9e pour la pass sanitaire (greenpass). Mais demain si une \u00e9volution sur la structure des donn\u00e9es voit le jour c&rsquo;est par cette valeur que nous le saurons.<\/p>\n\n\n\n<p>DOnc pour obtenir les donn\u00e9es utiles directement sans la version :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">zbarimg --raw --quiet qr_image.jpg | <span class=\"has-inline-color has-vivid-cyan-blue-color\">cut -b5- <\/span> # on enl\u00e8ve les 5 premiers bytes ...<\/code><\/pre>\n\n\n\n<p>ce qui donne :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\"><span class=\"has-inline-color has-vivid-purple-color\">00000000: 4e43 463a 3630 3341 3054 3957 5457 4753  NCF:603A0T9WTWGS\n00000010: 4c4b 4320 344b 3639 3457 4a4e 2e30 4a24  LKC 4K694WJN.0J$\n00000020: 3643 2d37 5741 4230 584b 334a 4353 4741  6C-7WAB0XK3JCSGA\n00000030: 3246 3352 3850 5034 5632 4633 3556 5050  2F3R8PP4V2F35VPP\n00000040: 2e45 5935 302e 464b 385a 4b4f 2f45 5a4b  .EY50.FK8ZKO\/EZK\n00000050: 455a 3936 4c46 362f 4136 2e2e 4456 2544  EZ96LF6\/A6..DV%D\n00000060: 5a4a 4330 2f44 3555 4120 5145 4c50 4347  ZJC0\/D5UA QELPCG\n00000070: 2f44 5955 4348 5938 3355 4147 5643 2a4a  \/DYUCHY83UAGVC*J\n00000080: 434e 4636 4634 3633 5735 4b46 3656 4636  CNF6F463W5KF6VF6\n00000090: 4945 4353 4847 344b 4344 3344 5834 3742  IECSHG4KCD3DX47B\n000000a0: 3436 494c 3636 3436 482a 364d 5745 574a  46IL6646H*6MWEWJ\n000000b0: 4441 3641 3a39 3631 4136 5134 3745 4d36  DA6A:961A6Q47EM6\n000000c0: 4224 4446 4f43 3052 3633 4b43 5a50 434e  B$DFOC0R63KCZPCN\n000000d0: 4636 4f46 3633 5735 2451 362b 3936 2f53  F6OF63W5$Q6+96\/S\n000000e0: 4135 5236 4e46 3631 4737 3335 3634 4b43  A5R6NF61G73564KC\n000000f0: 2a4b 4554 4636 4134 362e 3936 3634 3642  *KETF6A46.96646B\n00000100: 3536 3557 4543 2e44 3124 434b 5745 445a  565WEC.D1$CKWEDZ\n00000110: 4336 5643 5334 3436 2443 3457 4555 5043  C6VCS446$C4WEUPC\n00000120: 334a 4355 4941 2b45 4424 2e45 4624 444d  3JCUIA+ED$.EF$DM\n00000130: 5745 3824 4342 4a45 4d56 4342 3434 3524  WE8$CBJEMVCB445$\n00000140: 4342 5745 522e 4347 5043 3457 454f 5043  CBWER.CGPC4WEOPC\n00000150: 4538 4648 5a41 312b 394c 5a41 5a4d 3831  E8FHZA1+9LZAZM81\n00000160: 4737 3241 3632 2b38 4f47 374a 3039 5534  G72A62+8OG7J09U4\n00000170: 3741 4238 5635 3954 2536 5a48 424f 3537  7AB8V59T%6ZHBO57\n00000180: 5834 3852 5549 5930 3358 514f 4b2a 465a  X48RUIY03XQOK*FZ\n00000190: 554e 4d20 5546 5934 4435 4320 5333 5239  UNM UFY4D5C S3R9\n000001a0: 5557 2d32 522a 344b 5a4a 5435 4d20 4d49  UW-2R*4KZJT5M MI\n000001b0: 4d3a 3033 524d 5a4e 4120 4c4b 544f 3334  M:03RMZNA LKTO34\n000001c0: 5041 2e48 3531 3936 3650 5330 4b41 502d  PA.H51966PS0KAP-\n000001d0: 4b4c 5048 2e51 3624 4b53 544a 302d 4736  KLPH.Q6$KSTJ0-G6\n000001e0: 3538 524c 3548 5231 0a                   58RL5HR1.<\/span>\n<\/code><\/pre>\n\n\n\n<p>En l&rsquo;\u00e9tat les donn\u00e9es utiles sont illisibles. Nous allons maintenant voir comment tout cela est structur\u00e9.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"II3_Du_binaire_a_la_donnees_utiles\"><\/span>II.3 Du binaire \u00e0 la donn\u00e9es utiles<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"II31_Logique_de_la_structure_des_donnees\"><\/span>II.3.1 Logique de la structure des donn\u00e9es<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Les donn\u00e9es exploitables et visibles sont stock\u00e9es en format JSON int\u00e9gr\u00e9es dans un objet de type <a rel=\"noreferrer noopener\" href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc8949\" target=\"_blank\">CBOR<\/a> (<strong>C<\/strong>oncise <strong>B<\/strong>inary <strong>O<\/strong>bject <strong>R<\/strong>epresentation). Celui ci est lui-m\u00eame int\u00e9gr\u00e9 dans un objet de type <a rel=\"noreferrer noopener\" href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc8152\" target=\"_blank\">COSE<\/a> (<strong>C<\/strong>BOR <strong>O<\/strong>bject <strong>S<\/strong>ignature and <strong>E<\/strong>ncryption) et enfin cet objet COSE est compress\u00e9 (ZLIB) puis encod\u00e9 en <a rel=\"noreferrer noopener\" href=\"https:\/\/datatracker.ietf.org\/doc\/draft-faltstrom-base45\/07\/\" target=\"_blank\">base 45<\/a>.<\/p>\n\n\n\n<p>La donn\u00e9e binaire plus haut est donc est un objet de type \u00ab\u00a0COSE\u00a0\u00bb encod\u00e9 en base45 et compress\u00e9.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"II32_Recuperation_de_lobjet_%C2%AB_COSE_%C2%BB\"><\/span>II.3.2 R\u00e9cup\u00e9ration de l&rsquo;objet \u00ab\u00a0COSE\u00a0\u00bb<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Nous allons maintenant d\u00e9coder la donn\u00e9e encod\u00e9e en base 45 :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">zbarimg --raw --quiet qr_image.jpg | cut -b5- | <span class=\"has-inline-color has-vivid-cyan-blue-color\">base45 -d<\/span><\/code><\/pre>\n\n\n\n<p>Ce qui donne les donn\u00e9es compress\u00e9es suivantes :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">00000000: 78da 013a 01c5 fed2 844d a201 2604 4853  x..:.....M..&amp;.HS\n00000010: 9bef 0779 360a 3ea0 58e5 a401 6246 5206  ...y6.&gt;.X...bFR.\n00000020: 1a60 c744 f604 1a60 cb39 7639 0103 a101  .`.D...`.9v9....\n00000030: a463 7665 7265 312e 322e 3163 6e61 6da2  .cvere1.2.1cnam.\n00000040: 6266 6e64 5465 7374 6366 6e74 6454 4553  bfndTestcfntdTES\n00000050: 5463 646f 626a 3230 3039 2d30 322d 3238  Tcdobj2009-02-28\n00000060: 6174 81a9 6274 6769 3834 3035 3339 3030  at..btgi84053900\n00000070: 3662 7474 6a4c 5032 3137 3139 382d 3362  6bttjLP217198-3b\n00000080: 6d61 6333 3435 6273 6374 3230 3231 2d30  mac345bsct2021-0\n00000090: 342d 3133 5431 343a 3230 3a30 305a 6274  4-13T14:20:00Zbt\n000000a0: 7269 3236 3034 3135 3030 3062 7463 6e43  ri260415000btcnC\n000000b0: 656e 7472 6520 6465 2074 6573 7462 636f  entre de testbco\n000000c0: 6246 5262 6973 7645 6d65 7474 6575 7220  bFRbisvEmetteur \n000000d0: 6475 2063 6572 7469 6669 6361 7462 6369  du certificatbci\n000000e0: 781d 5552 4e3a 5556 4349 3a30 313a 4652  x.URN:UVCI:01:FR\n000000f0: 3a47 4744 3831 4141 4831 3641 5a23 3858  :GGD81AAH16AZ#8X\n00000100: 401d 93c3 17dd c28b 7d96 bb58 f3b8 25ad  @.......}..X..%.\n00000110: 5fda 1ccb eefe 1727 269a 9c86 af04 9264  _......'&amp;......d\n00000120: 07d2 b2c8 5348 a209 1c10 5383 2ab4 310c  ....SH....S.*.1.\n00000130: e1e7 529e a582 8af3 3432 e125 0374 326f  ..R.....42.%.t2o\n00000140: d700 876f f95f                           ...o._\n<\/code><\/pre>\n\n\n\n<p>A ce stade la donn\u00e9e est compress\u00e9e &#8230; d\u00e9compressons l\u00e0 :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">zbarimg --raw --quiet qr_image.jpg | cut -b5- | base45 -d | <span class=\"has-inline-color has-vivid-cyan-blue-color\">zlib-flate -uncompress<\/span><\/code><\/pre>\n\n\n\n<p>Ce qui donne les donn\u00e9es binaires de l&rsquo;objet COSE suivant :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">00000000: <strong>d2<\/strong>84 4da2 0126 0448 539b ef07 7936 0a3e  ..M..&amp;.HS...y6.&gt;\n00000010: a058 e5a4 0162 4652 061a 60c7 44f6 041a  .X...bFR..`.D...\n00000020: 60cb 3976 3901 03a1 01a4 6376 6572 6531  `.9v9.....cvere1\n00000030: 2e32 2e31 636e 616d a262 666e 6454 6573  .2.1cnam.bfndTes\n00000040: 7463 666e 7464 5445 5354 6364 6f62 6a32  tcfntdTESTcdobj2\n00000050: 3030 392d 3032 2d32 3861 7481 a962 7467  009-02-28at..btg\n00000060: 6938 3430 3533 3930 3036 6274 746a 4c50  i840539006bttjLP\n00000070: 3231 3731 3938 2d33 626d 6163 3334 3562  217198-3bmac345b\n00000080: 7363 7432 3032 312d 3034 2d31 3354 3134  sct2021-04-13T14\n00000090: 3a32 303a 3030 5a62 7472 6932 3630 3431  :20:00Zbtri26041\n000000a0: 3530 3030 6274 636e 4365 6e74 7265 2064  5000btcnCentre d\n000000b0: 6520 7465 7374 6263 6f62 4652 6269 7376  e testbcobFRbisv\n000000c0: 456d 6574 7465 7572 2064 7520 6365 7274  Emetteur du cert\n000000d0: 6966 6963 6174 6263 6978 1d55 524e 3a55  ificatbcix.URN:U\n000000e0: 5643 493a 3031 3a46 523a 4747 4438 3141  VCI:01:FR:GGD81A\n000000f0: 4148 3136 415a 2338 5840 1d93 c317 ddc2  AH16AZ#8X@......\n00000100: 8b7d 96bb 58f3 b825 ad5f da1c cbee fe17  .}..X..%._......\n00000110: 2726 9a9c 86af 0492 6407 d2b2 c853 48a2  '&amp;......d....SH.\n00000120: 091c 1053 832a b431 0ce1 e752 9ea5 828a  ...S.*.1...R....\n00000130: f334 32e1 2503 7432 6fd7                 .42.%.t2o.\n<\/code><\/pre>\n\n\n\n<p>On commence \u00e0 apercevoir des donn\u00e9es&#8230;<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"II33_Analyse_de_lobjet_COSE\"><\/span>II.3.3 Analyse de l&rsquo;objet COSE<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Nous avons donc un objet COSE qui se lit comme un objet CBOR.  La particularit\u00e9 de ce type d&rsquo;objet est de pouvoir signer un contenu et\/ou de le chiffrer.<\/p>\n\n\n\n<p>Un objet COSE peut \u00eatre de 6 types diff\u00e9rents :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">   +-------+---------------+---------------+---------------------------+\n   | CBOR  | cose-type     | Data Item     | Semantics                 |\n   | Tag   |               |               |                           |\n   +-------+---------------+---------------+---------------------------+\n   | 98    | cose-sign     | COSE_Sign     | COSE Signed Data Object   |\n   | 18    | cose-sign1    | COSE_Sign1    | COSE Single Signer Data   |\n   |       |               |               | Object                    |\n   | 96    | cose-encrypt  | COSE_Encrypt  | COSE Encrypted Data       |\n   |       |               |               | Object                    |\n   | 16    | cose-encrypt0 | COSE_Encrypt0 | COSE Single Recipient     |\n   |       |               |               | Encrypted Data Object     |\n   | 97    | cose-mac      | COSE_Mac      | COSE MACed Data Object    |\n   | 17    | cose-mac0     | COSE_Mac0     | COSE Mac w\/o Recipients   |\n   |       |               |               | Object                    |\n   +-------+---------------+---------------+---------------------------+<\/code><\/pre>\n\n\n\n<p>Le type est renseign\u00e9 dans le 1er octet dans le flux de donn\u00e9s qui compose l&rsquo;objet COSE. Pour nous c&rsquo;est la valeur <strong>d2<\/strong>.<\/p>\n\n\n\n<p>Or la donn\u00e9e <strong>D2<\/strong> ne correspond pas \u00e0 une des valeurs \u00ab\u00a0CBOR Tag\u00a0\u00bb.  Pour comprendre comment sont encod\u00e9es les informations dans un CBOR il est n\u00e9cessaire de lire les sp\u00e9cifications d\u00e9di\u00e9es \u00e0 cet objet : <a rel=\"noreferrer noopener\" href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc7049#section-2\" target=\"_blank\">https:\/\/datatracker.ietf.org\/doc\/html\/rfc7049#section-2<\/a>.<\/p>\n\n\n\n<p>Dans l&rsquo;id\u00e9e, pour un octet encod\u00e9 il y a 2 informations stock\u00e9es : sur les 3 premiers bits un type est renseign\u00e9 (Major type) et sur les bits restants des informations additionnelles.<\/p>\n\n\n\n<p>Donc notre information \u00ab\u00a0<strong>D2<\/strong>\u00a0\u00bb en binaire correspond \u00e0 <span class=\"has-inline-color has-vivid-red-color\">110<\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">10010<\/span> soit :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><span class=\"has-inline-color has-vivid-red-color\"><strong>110<\/strong><\/span> pour le Major Type : <strong>6<\/strong> en d\u00e9cimal cela correspond \u00e0 une donn\u00e9e de type \u00ab\u00a0optional semantic tagging of other major types\u00a0\u00bb<ul><li>le type est non assign\u00e9 (cf <a rel=\"noreferrer noopener\" href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc7049#section-2.4\" target=\"_blank\">sp\u00e9cification<\/a>) ;<\/li><li>comme nous sommes sur un objet COSE, cela correspond au type de COSE. le type d&rsquo;attribut \u00e9tant \u00ab\u00a0<a rel=\"noreferrer noopener\" href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc8152#section-3.1\" target=\"_blank\">ALG<\/a>\u00a0\u00bb ;<\/li><\/ul><\/li><li><span class=\"has-inline-color has-vivid-green-cyan-color\"><strong>10010<\/strong><\/span> pour les donn\u00e9es additionnelles qui correspond \u00e0 la valeur d\u00e9cimale <strong>18<\/strong> ;<ul><li>la valeur 18 que l&rsquo;on retrouve dans le tableau de types de COSE et qui indique que ce COSE comporte de la donn\u00e9e avec une signature.<\/li><\/ul><\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>Ainsi, dans notre cas cet objet COSE doit comporter :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>une ent\u00eate (prot\u00e9g\u00e9e et non prot\u00e9g\u00e9e) ;<\/li><li>un payload, ou le contenu (ici l&rsquo;objet CBOR recherch\u00e9) ;<\/li><li>une signature.<\/li><\/ul>\n\n\n\n<p>Nous allons continuer \u00e0 d\u00e9coder manuellement les donn\u00e9es&#8230;<\/p>\n\n\n\n<p>La donn\u00e9e suivante est \u00ab\u00a084\u00a0\u00bb :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">00000000: d2<strong>84<\/strong> 4da2 0126 0448 539b ef07 7936 0a3e  ..M..&amp;.HS...y6.&gt;<\/code><\/pre>\n\n\n\n<p>Donc 84 donne 10000100 soit une major type 4 (100b) et des donn\u00e9es additionnelles indiquant 4 (00100b) : Cela indique un tableau (Major Type 4) de taille 4 (donn\u00e9es additionnelles).<\/p>\n\n\n\n<p>La donn\u00e9e suivante est \u00ab\u00a04d\u00a0\u00bb :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">00000000: d284 <strong>4d<\/strong>a2 0126 0448 539b ef07 7936 0a3e  ..M..&amp;.HS...y6.&gt;<\/code><\/pre>\n\n\n\n<p>Donc <strong>4d<\/strong> donne 01001101 soit 010 qui indique un type de donn\u00e9es bytes (Major type 010 soit 4) avec une taille de 13 octets (donn\u00e9es additionnelles  01101b soit 13).<\/p>\n\n\n\n<p>Ainsi la prochaine s\u00e9quence consiste \u00e0 r\u00e9cup\u00e9rer les 13 octets suivants :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">00000000: d284 <strong>4d<\/strong><span class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>a2 0126 0448 539b ef07 7936<\/strong><\/span> <strong><span class=\"has-inline-color has-vivid-cyan-blue-color\">0a3e<\/span><\/strong>  ..<strong>M<span class=\"has-inline-color has-vivid-cyan-blue-color\">..&amp;.HS...y6.&gt;<\/span><\/strong>\n00000010: <span class=\"has-inline-color has-black-color\">a058<\/span> e5a4 0162 4652 061a 60c7 44f6 041a  .X...bFR..`.D...\n00000020: 60cb 3976 3901 03a1 01a4 6376 6572 6531  `.9v9.....cvere1\n00000030: 2e32 2e31 636e 616d a262 666e 6454 6573  .2.1cnam.bfndTes<\/code><\/pre>\n\n\n\n<p>En CBOR ces donn\u00e9es n&rsquo;ont pas de signification. Mais pour rappel nous sommes dans un objet COSE. Et l\u00e0 cette donn\u00e9e \u00ab\u00a0<span class=\"has-inline-color has-black-color\">A201260448539BEF0779360A3E<\/span>\u00a0\u00bb correspond \u00e0 l&rsquo;ent\u00eate prot\u00e9g\u00e9e (Voir les <a rel=\"noreferrer noopener\" href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc8152#section-4.2\" target=\"_blank\">sp\u00e9cifications CBOR<\/a>) Le <a rel=\"noreferrer noopener\" href=\"https:\/\/ec.europa.eu\/health\/sites\/default\/files\/ehealth\/docs\/digital-green-certificates_v3_en.pdf\" target=\"_blank\">document europ\u00e9en \u00a72.4 <\/a>indique la raison et l&rsquo;utilit\u00e9 de cette valeur : hash d&rsquo;une clef  de chiffrement tronqu\u00e9 sur 8 octets. Cette information est nomm\u00e9e Kid ou Key Identification. Nous v\u00e9rrons dans le paragraphe &lsquo;v\u00e9rification d&rsquo;un QR-Code\u00a0\u00bb comment utiliser ce type de donn\u00e9es.<\/p>\n\n\n\n<p>Pour continuer la lecture du document il suffit d&rsquo;appliquer le m\u00eame principe, ce qui donne les blocs suivants:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">00000000: <strong>d2<\/strong>84 <strong>4d<\/strong><span class=\"has-inline-color has-vivid-cyan-blue-color\">a2 0126 0448 539b ef07 7936 0a3e<\/span>  ..M..&amp;.HS...y6.&gt;\n00000010: <strong>a0<span class=\"has-inline-color has-cyan-bluish-gray-color\">58 e5<\/span><\/strong><span class=\"has-inline-color has-vivid-green-cyan-color\">a4 0162 4652 061a 60c7 44f6 041a  .X...bFR..`.D...\n00000020: 60cb 3976 3901 03a1 01a4 6376 6572 6531  `.9v9.....cvere1\n00000030: 2e32 2e31 636e 616d a262 666e 6454 6573  .2.1cnam.bfndTes\n00000040: 7463 666e 7464 5445 5354 6364 6f62 6a32  tcfntdTESTcdobj2\n00000050: 3030 392d 3032 2d32 3861 7481 a962 7467  009-02-28at..btg\n00000060: 6938 3430 3533 3930 3036 6274 746a 4c50  i840539006bttjLP\n00000070: 3231 3731 3938 2d33 626d 6163 3334 3562  217198-3bmac345b\n00000080: 7363 7432 3032 312d 3034 2d31 3354 3134  sct2021-04-13T14\n00000090: 3a32 303a 3030 5a62 7472 6932 3630 3431  :20:00Zbtri26041\n000000a0: 3530 3030 6274 636e 4365 6e74 7265 2064  5000btcnCentre d\n000000b0: 6520 7465 7374 6263 6f62 4652 6269 7376  e testbcobFRbisv\n000000c0: 456d 6574 7465 7572 2064 7520 6365 7274  Emetteur du cert\n000000d0: 6966 6963 6174 6263 6978 1d55 524e 3a55  ificatbcix.URN:U\n000000e0: 5643 493a 3031 3a46 523a 4747 4438 3141  VCI:01:FR:GGD81A\n000000f0: 4148 3136 415a 2338<\/span> <strong>5840<\/strong> <span class=\"has-inline-color has-vivid-purple-color\">1d93 c317 ddc2  AH16AZ#8X@......\n00000100: 8b7d 96bb 58f3 b825 ad5f da1c cbee fe17  .}..X..%._......\n00000110: 2726 9a9c 86af 0492 6407 d2b2 c853 48a2  '&amp;......d....SH.\n00000120: 091c 1053 832a b431 0ce1 e752 9ea5 828a  ...S.*.1...R....\n00000130: f334 32e1 2503 7432 6fd7                 .42.%.t2o.<\/span><\/code><\/pre>\n\n\n\n<p>Nous avons donc nos 4 sections de l&rsquo;objet COSE:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><span class=\"has-inline-color has-vivid-cyan-blue-color\">l&rsquo;ent\u00eate prot\u00e9g\u00e9e<\/span> ;<\/li><li>l\u2019ent\u00eate en clair (vide dans notre cas) ;<\/li><li><span class=\"has-inline-color has-vivid-green-cyan-color\">le payload<\/span> (l&rsquo;objet CBOR recherch\u00e9) ;<\/li><li><span class=\"has-inline-color has-vivid-purple-color\">la signature<\/span>.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"III_Lecture_de_lobjet_CBOR_donnees_utiles_concernant_le_pass_sanitaire\"><\/span>III Lecture de l&rsquo;objet CBOR (donn\u00e9es utiles concernant le pass sanitaire)<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Les donn\u00e9es utiles sont dans le payload. Cette donn\u00e9e est sous format CBOR.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"III1_Donnees_binaires_du_CBOR\"><\/span>III.1 Donn\u00e9es binaires du CBOR<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Ainsi les donn\u00e9es utiles sont les suivantes :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">A401624652061A60C744F6041A60CB3976390103A101A46376657265312E322E31636E616DA262666E645465737463666E74645445535463646F626A323030392D30322D3238617481A9627467693834303533393030366274746A4C503231373139382D33626D616333343562736374323032312D30342D31335431343A32303A30305A627472693236303431353030306274636E43656E747265206465207465737462636F62465262697376456D6574746575722064752063657274696669636174626369781D55524E3A555643493A30313A46523A47474438314141483136415A2338<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"III2_Decodage_du_CBOR\"><\/span>III.2 D\u00e9codage du CBOR<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Sans d\u00e9coder \u00e0 la main et apr\u00e8s \u00eatre pass\u00e9 via  un <a rel=\"noreferrer noopener\" href=\"http:\/\/cbor.me\/\" target=\"_blank\">parseur<\/a> CBOR en ligne nous obtenons les donn\u00e9es lisibles suivantes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">{1: \"FR\", 6: 1623672054, 4: 1623931254, -260: {1: {\"ver\": \"1.2.1\", \"nam\": {\"fn\": \"Test\", \"fnt\": \"TEST\"}, \"dob\": \"2009-02-28\", \"t\": [{\"tg\": \"840539006\", \"tt\": \"LP217198-3\", \"ma\": \"345\", \"sc\": \"2021-04-13T14:20:00Z\", \"tr\": \"260415000\", \"tc\": \"Centre de test\", \"co\": \"FR\", \"is\": \"Emetteur du certificat\", \"ci\": \"URN:UVCI:01:FR:GGD81AAH16AZ#8\"}]}}}<\/code><\/pre>\n\n\n\n<p>Nous avons donc la structure JSON binaire suivante (non correcte pour les 4 premi\u00e8res lignes du point de vue du format JSON standard car les chiffres doivent \u00eatre entre guillemet)  : <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">{\n  1: \"FR\",\n  4: 1623931254,\n  6: 1623672054,\n  -260: <span class=\"has-inline-color has-vivid-cyan-blue-color\">{\n    \"1\": {\n      \"ver\": \"1.2.1\",\n      \"nam\": {\n        \"fn\": \"Test\",\n        \"fnt\": \"TEST\"\n      },\n      \"dob\": \"2009-02-28\",\n      \"t\": <\/span>\n          <span class=\"has-inline-color has-vivid-cyan-blue-color\">[{\n          \"tg\": \"840539006\",\n          \"tt\": \"LP217198-3\",\n          \"ma\": \"345\",\n          \"sc\": \"2021-04-13T14:20:00Z\",\n          \"tr\": \"260415000\",\n          \"tc\": \"Centre de test\",\n          \"co\": \"FR\",\n          \"is\": \"Emetteur du certificat\",\n          \"ci\": \"URN:UVCI:01:FR:GGD81AAH16AZ#8\"\n          }]\n         }<\/span>\n        }\n}<\/code><\/pre>\n\n\n\n<p>Cette architecture des donn\u00e9es est sp\u00e9cifi\u00e9e dans les document europ\u00e9ens et qui doit prendre la forme suivante (<a rel=\"noreferrer noopener\" href=\"https:\/\/ec.europa.eu\/health\/sites\/default\/files\/ehealth\/docs\/digital-green-certificates_v3_en.pdf\" target=\"_blank\">cf lien, chapitre 2.6.3<\/a>) :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/08\/CBOR-structure-EE.png\" alt=\"\" class=\"wp-image-2644\" width=\"562\" height=\"226\" srcset=\"https:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/08\/CBOR-structure-EE.png 993w, https:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/08\/CBOR-structure-EE-300x121.png 300w, https:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/08\/CBOR-structure-EE-768x309.png 768w\" sizes=\"auto, (max-width: 562px) 100vw, 562px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"III3_Les_donnees_utiles_dans_le_CBOR\"><\/span>III.3 Les donn\u00e9es utiles dans le CBOR<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Ainsi en bleu les donn\u00e9es utiles dans le JSON plus haut.<\/p>\n\n\n\n<p>Pour conna\u00eetre la signification des cl\u00e9s\/valeurs il faut se r\u00e9f\u00e9rer aux sp\u00e9cifications EU dont ce <a rel=\"noreferrer noopener\" href=\"https:\/\/ec.europa.eu\/health\/sites\/default\/files\/ehealth\/docs\/covid-certificate_json_specification_en.pdf\" target=\"_blank\">lien<\/a> sp\u00e9cifie le nom des champs utilis\u00e9s dans le texte en bleu.<\/p>\n\n\n\n<p>Ce qui donne les valeurs suivantes plus lisibles :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\"><span class=\"has-inline-color has-vivid-cyan-blue-color\">{\n    \"1\": {                <\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">--&gt; 1er enregistrement<\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\">\n      \"ver\": \"1.2.1\",     <\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">--&gt; Version du sch\u00e9la JSON utilis\u00e9\n      <\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\">\"nam\": {<\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">            --&gt; Nom de la personne\n       <\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\"> \"fn\": \"Test\",<\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">      --&gt; Nom de famille\n        <\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\">\"fnt\": \"TEST\"<\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">      --&gt; Nom de famille standardis\u00e9\n      <\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\">},<\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">\n      <\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\">\"dob\": \"2009-02-28\",<\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">  --&gt; Date de naissance\n      <\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\">\"t\": <\/span>                                          <span class=\"has-inline-color has-vivid-green-cyan-color\">--&gt; Groupe de test<\/span>\n          <span class=\"has-inline-color has-vivid-cyan-blue-color\">[{\n          \"tg\": \"840539006\",                           <\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">--&gt; Maladie ou agent cibl\u00e9 : 840539006 indique que c'est le COVID-19<\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\">\n          \"tt\": \"LP217198-3\",<span class=\"has-inline-color has-vivid-cyan-blue-color\">                 <\/span><\/span>         <span class=\"has-inline-color has-vivid-green-cyan-color\">--&gt; Type de test utilis\u00e9 : LP217198-3 indique Test immunologique rapide<\/span>    <span class=\"has-inline-color has-vivid-cyan-blue-color\">\n          \"ma\": \"345\",                                 <\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">--&gt; Type d'appareil de test (pour le test immunologique seulement : 345<\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\"> \n          \"sc\": \"2021-04-13T14:20:00Z\",                <\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">--&gt; Date et heure du test :le 13 avril 2021 \u00e0 14:20<\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\">\n          \"tr\": \"260415000\",                           <\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">--&gt; R\u00e9sultat du test : 260415000 indique non d\u00e9tect\u00e9<\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\">\n          \"tc\": \"Centre de test\",                      <\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">--&gt; Centre de test<\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\">\n          \"co\": \"FR\",                                  <\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">--&gt; Pays : FR indique France<\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\">\n          \"is\": \"Emetteur du certificat\",              <\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">--&gt; Emetteur du certificat<\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\">\n          \"ci\": \"URN:UVCI:01:FR:GGD81AAH16AZ#8\"        <\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">--&gt; Identifiant Unique du certificat<\/span><span class=\"has-inline-color has-vivid-cyan-blue-color\">\n          }]\n         }<\/span>\n<span class=\"has-inline-color has-vivid-cyan-blue-color\">}<\/span><\/code><\/pre>\n\n\n\n<p>A ce stade bous avons retrouv\u00e9 l&rsquo;ensemble des donn\u00e9es utiles ainsi que leurs significations.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"IV_Avec_un_QR-CODE_dun_vrai_passe_sanitaire%E2%80%A6\"><\/span>IV Avec un QR-CODE d&rsquo;un vrai passe sanitaire&#8230;<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Nous avons vu comment r\u00e9cup\u00e9rer les informations utiles avec un QR-CODE de test.<\/p>\n\n\n\n<p>Utilisons un vrai QR-Code afin de v\u00e9rifier le process et de visualiser les donn\u00e9es finales  quand on est d\u00e9clar\u00e9 officiellement vaccin\u00e9 et apr\u00e8s avoir re\u00e7u le papier \u00ab\u00a0CERTIFICAT COVID NUMERIQUE EU\u00a0\u00bb.<\/p>\n\n\n\n<p>Sans reprendre tout le process de d\u00e9codage, nous allons nous concentrer sur le r\u00e9sultat final qui  donne le json suivant :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">{\n  \"v\": [                                          --&gt; Groupe de vaccination\n    {\n      \"ci\": \"urn:uvci:01:FR:XXXXXXXXXXXXXX\",      --&gt; Identifiant unique du certificat (j'ai modifi\u00e9 les valeurs...) \n      \"co\": \"FR\",                                 --&gt; Pays : France\n      \"dn\": 1,                                    --&gt; Nombre de doses : 1 ici (oui j'ai eu le COVID, donc une seul dose)\n      \"dt\": \"2021-07-24\",                         --&gt; Date de la vaccination\n      \"is\": \"CNAM\",                               --&gt; Nom de l'organisation qui a fait ce certificat : la CNAM\n      \"ma\": \"ORG-100030215\",                      --&gt; Num\u00e9ro d\u2019autorisation du vaccin\n      \"mp\": \"EU\/1\/20\/1528\",                       --&gt; Num\u00e9ro de produit du vaccin\n      \"sd\": 1,                                    --&gt; Nombre total de dose pour \u00eatre compl\u00e8tement vaccin\u00e9\n      \"tg\": \"840539006\",                          --&gt; Maladie ou agent cibl\u00e9 : 840539006 indique le COVID\n      \"vp\": \"J07BX03\"                             --&gt; Type de vaccin : J07BX03 indique Pfizer-BioNTech\n    }\n  ],\n  \"dob\": \"1976-12-27\",                            --&gt; date de naissance\n  \"nam\": {                                        --&gt; Nom et pr\u00e9nom (j'ai modifi\u00e9 les valeurs...)\n    \"fn\": \"MonNOM\",\n    \"gn\": \"MonPr\u00e9nom\",\n    \"fnt\": \"MonNOM\",\n    \"gnt\": \"MonPr\u00e9nom\"\n  },\n  \"ver\": \"1.3.0\"                                  --&gt; version du sch\u00e9ma JSON utilis\u00e9\n}<\/code><\/pre>\n\n\n\n<p>En regardant les r\u00e9sultats nous obtenons donc les valeurs qui sont enregistr\u00e9es dans un vrai QR-CODE pour le passe sanitaire.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"V_Verification_du_QR-CODE\"><\/span>V V\u00e9rification du QR-CODE<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"V1_Introduction\"><\/span>V.1 Introduction<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Nous allons maintenant voir comment v\u00e9rifier si un QR-CODE est int\u00e8gre ou non contenu valide. Pour cela il faut :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>une clef publique qui va nous permettre de v\u00e9rifier le contenu du QR-Code ;<\/li><li>la signature du QR-Code ;<\/li><li>la donn\u00e9e utile \u00e0 v\u00e9rifier (le payload mais c&rsquo;est l\u00e9g\u00e8rement plus compliqu\u00e9 au final).<\/li><\/ul>\n\n\n\n<p>Nous avons vu que l&rsquo;objet COSE r\u00e9cup\u00e9r\u00e9 comportait 3 parties utiles :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>une partie ent\u00eate : qui contient le KID (Key IDdentification) &#8211; ce dernier nous indique quelle clef publique il faut utiliser ;<\/li><li>une partie payload : le contenu CBOR (que nous avons vu au-dessus) ;<\/li><li>une partie signature : l&rsquo;information qui certifie que le contenu CBOR est vrai, c&rsquo;est \u00e0 dire sign\u00e9e par la clef priv\u00e9 de celui qui g\u00e9n\u00e8re ces informations.<\/li><\/ul>\n\n\n\n<p>Les paragraphes suivants vont montrer comment r\u00e9cup\u00e9rer la clef publique, pr\u00e9parer la signature (il faudra changer de format) et pr\u00e9parer le message \u00e0 v\u00e9rifer (utilisation d&rsquo;une structure particuli\u00e8re. Une fois ces 3 \u00e9l\u00e9ments en possession nous pourrons alors v\u00e9rifier avec OpenSsl l&rsquo;int\u00e9grit\u00e9 des informations ou non.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"V2_Recuperation_de_la_clef_publique\"><\/span>V.2 R\u00e9cup\u00e9ration de la clef publique<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"V21_Partie_entete_recuperation_du_Key_Identifier_Kid\"><\/span>V.2.1 Partie ent\u00eate : r\u00e9cup\u00e9ration du Key Identifier (Kid)<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Il est sp\u00e9cifi\u00e9 dans le <a rel=\"noreferrer noopener\" href=\"https:\/\/ec.europa.eu\/health\/sites\/default\/files\/ehealth\/docs\/digital-green-certificates_v3_en.pdf\" target=\"_blank\">document<\/a> (paragraphe 2.6.1 et 2.6.2) que l\u2019ent\u00eate prot\u00e9g\u00e9e ou non peut \u00eatre utilis\u00e9e pour y stocker l&rsquo;information \u00ab\u00a0KID\u00a0\u00bb. De plus le format est du type suivant :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"796\" height=\"189\" src=\"http:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/11\/COSE_data_type_header.png\" alt=\"\" class=\"wp-image-2856\" srcset=\"https:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/11\/COSE_data_type_header.png 796w, https:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/11\/COSE_data_type_header-300x71.png 300w, https:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/11\/COSE_data_type_header-768x182.png 768w\" sizes=\"auto, (max-width: 796px) 100vw, 796px\" \/><\/figure>\n\n\n\n<p>Donc dans notre cas, l&rsquo;ent\u00eate est la suivante :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">D2                                      # tag(18)\n   84                                   # array(4)\n      4D                                # bytes(13)\n         A20448D6FC694CB81CEB0B0126     # \"\\xA2\\x04H\\xD6\\xFCiL\\xB8\\x1C\\xEB\\v\\x01&amp;\"<\/code><\/pre>\n\n\n\n<p>Ainsi pour la valeur d&rsquo;ent\u00eate \u00ab\u00a0A20448D6FC694CB81CEB0B0126\u00a0\u00bb nous avons :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">A2                     # map(2)\n   04                  # unsigned(4)                 --&gt; champ Kid\n   48                  # bytes(8)\n      D6FC694CB81CEB0B # \"\\xD6\\xFCiL\\xB8\\x1C\\xEB\\v\"   --&gt; valeur Kid\n   01                  # unsigned(1)                 --&gt; champ alg\n   26                  # negative(6)<\/code><\/pre>\n\n\n\n<p>Le KID est donc \u00ab\u00a0<strong>D6FC694CB81CEB0B<\/strong>\u00ab\u00a0. Attention ce kid vient d&rsquo;un QR-code de test et nous ne pourrons pas retrouver la clef publique d&rsquo;un \u00e9tat membre.<\/p>\n\n\n\n<p>Maintenant si on prend une ent\u00eate d&rsquo;un vrai QR-Code :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">A2                     # map(2)\n   01                  # unsigned(1)\n   26                  # negative(6)\n   04                  # unsigned(4)\n   48                  # bytes(8)\n      7C62EEBE0EA7E709 # \"|b\\xEE\\xBE\\x0E\\xA7\\xE7\\t\"<\/code><\/pre>\n\n\n\n<p>le KID est \u00ab\u00a07C62EEBE0EA7E709\u00a0\u00bb. Attention il est cod\u00e9 en base64, donc en texte :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">echo \"7C62EEBE0EA7E709\" | xxd -r -p | base64<\/code><\/pre>\n\n\n\n<p>Ce qui nous donne : \u00ab\u00a0<strong>fGLuvg6n5wk=<\/strong>\u00ab\u00a0<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"V22_Clef_publique\"><\/span>V.2.2 Clef publique<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"V221_Recuperation_de_la_clef_publique\"><\/span>V.2.2.1 R\u00e9cup\u00e9ration de la clef publique<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p>Maintenant que nous avons le \u00ab\u00a0Key Identifier\u00a0\u00bb de la clef publique, nous pouvons r\u00e9cup\u00e9rer la clef publique qui va nous permettre de savoir si ce QR-Code est int\u00e8gre ou non dans son contenu.<\/p>\n\n\n\n<p>Un projet Github rescence l&rsquo;ensemble des clefs publiques utilis\u00e9es par les \u00e9tats-membres :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>site github : <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/lovasoa\/sanipasse\/\" target=\"_blank\">https:\/\/github.com\/lovasoa\/sanipasse\/<\/a><\/li><li>lien ressource json qui contient les clefs : <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/lovasoa\/sanipasse\/blob\/master\/src\/assets\/Digital_Green_Certificate_Signing_Keys.json\" target=\"_blank\">https:\/\/github.com\/lovasoa\/sanipasse\/blob\/master\/src\/assets\/Digital_Green_Certificate_Signing_Keys.json<\/a><\/li><\/ul>\n\n\n\n<p>Donc pour trouver la clef publique qui a \u00e9t\u00e9 utilis\u00e9e il faut rechercher dans le fichier \u00ab\u00a0Digital_Green_Certificate_Signing_Keys.json\u00a0\u00bb. Ainsi pour le \u00ab\u00a0Kid\u00a0\u00bb ayant la valeur \u00ab\u00a0<strong>fGLuvg6n5wk=<\/strong>\u00a0\u00bb nous retrouvons le certificat suivant :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">\"fGLuvg6n5wk=\": {\n\t\t\"serialNumber\": \"3563bbfbfda59864064f571ea79a5eb5fb0e1687\",\n\t\t\"subject\": \"C=FR, O=CNAM, OU=180035024, CN=DSC_FR_019\",\n\t\t\"issuer\": \"C=FR, O=Gouv, CN=CSCA-FRANCE\",\n\t\t\"notBefore\": \"2021-06-14T22:00:00.000Z\",\n\t\t\"notAfter\": \"2023-06-14T22:00:00.000Z\",\n\t\t\"signatureAlgorithm\": \"RSASSA-PKCS1-v1_5\",\n\t\t\"fingerprint\": \"2d53de4c89a1f5a5a901312e8ffe7e1c5573a852\",\n\t\t\"publicKeyAlgorithm\": {\n\t\t\t\"hash\": {\n\t\t\t\t\"name\": \"SHA-256\"\n\t\t\t},\n\t\t\t\"name\": \"ECDSA\",\n\t\t\t\"namedCurve\": \"P-256\"\n\t\t},\n\t\t\"publicKeyPem\": \"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEImIFaugzwB5f\/VyfQ3KTfTSoukwAPVSgHZWrtrc2j4FuAUpw\/ObRnA9pBjN\/HdUc1zcl9SO\/vsCEnHkXhxjz4Q==\"\n\t}<\/code><\/pre>\n\n\n\n<p>La valeur de la clef publique est dans le champ \u00ab\u00a0publicKeyPem\u00a0\u00bb.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"V222_Creation_du_fichier_de_la_clef_publique\"><\/span>V.2.2.2 Cr\u00e9ation du fichier de la clef publique<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p>Pour traiter des fichiers JSON via le shell nous allons utiliser le package \u00ab\u00a0jq\u00a0\u00bb :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">sudo apt install jq<\/code><\/pre>\n\n\n\n<p>Pour plus d&rsquo;informations sur ce package :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>projet officiel : <a rel=\"noreferrer noopener\" href=\"https:\/\/stedolan.github.io\/jq\/\" target=\"_blank\">https:\/\/stedolan.github.io\/jq\/<\/a><\/li><li>exemples d&rsquo;utilisation : <a rel=\"noreferrer noopener\" href=\"https:\/\/blog.lecacheur.com\/2016\/02\/16\/jq-manipuler-du-json-en-shell\/\" target=\"_blank\">https:\/\/blog.lecacheur.com\/2016\/02\/16\/jq-manipuler-du-json-en-shell\/<\/a><\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>Dans un premier temps nous allons r\u00e9cup\u00e9rer le fichier :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># t\u00e9l\u00e9chargement du fichier JSON\nwget https:\/\/raw.githubusercontent.com\/lovasoa\/sanipasse\/master\/src\/assets\/Digital_Green_Certificate_Signing_Keys.json<\/code><\/pre>\n\n\n\n<p>Puis \u00e0 partir de ce fichier, nous cr\u00e9oons un fichier contenant la clef publique qui nous int\u00e9resse :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">echo \"-----BEGIN PUBLIC KEY-----\" &gt; public_key.pem\ncat Digital_Green_Certificate_Signing_Keys.json | jq --raw-output --arg kid \"<strong>fGLuvg6n5wk=<\/strong>\" '.[$kid].publicKeyPem' &gt;&gt; public_key.pem\necho \"-----END PUBLIC KEY-----\" &gt;&gt; public_key.pem<\/code><\/pre>\n\n\n\n<p>Ce qui nous donne le fichier public_key.pem avec le contenu suivant :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEImIFaugzwB5f\/VyfQ3KTfTSoukwAPVSgHZWrtrc2j4FuAUpw\/ObRnA9pBjN\/HdUc1zcl9SO\/vsCEnHkXhxjz4Q==\n-----END PUBLIC KEY-----\n<\/code><\/pre>\n\n\n\n<p>et pour v\u00e9rifier :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">openssl asn1parse -in public_key.pem -inform PEM\n\n    0:d=0  hl=2 l=  89 cons: SEQUENCE          \n    2:d=1  hl=2 l=  19 cons: SEQUENCE          \n    4:d=2  hl=2 l=   7 prim: OBJECT            :id-ecPublicKey\n   13:d=2  hl=2 l=   8 prim: OBJECT            :prime256v1\n   23:d=1  hl=2 l=  66 prim: BIT STRING        \n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"V3_Recuperation_et_traitement_de_la_signature_du_QR-CODE\"><\/span>V.3 R\u00e9cup\u00e9ration et traitement de la signature du QR-CODE<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"V31_Avant_de_commencer\"><\/span>V.3.1 Avant de commencer<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Comme le sp\u00e9cifie le document europ\u00e9en, l&rsquo;algorithme de signature utilise l'\u00a0\u00bbECDSA w\/ SHA-256&Prime; <\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/11\/COSE_data_type_header.png\" alt=\"L\u2019attribut alt de cette image est vide, son nom de fichier est COSE_data_type_header.png.\" width=\"552\" height=\"131\"\/><\/figure>\n\n\n\n<p>Dans la sp\u00e9cification COSE utilisant une signature de type ECDSA le format de signature suit la r\u00e8gle suivante : la signature est la concat\u00e9nation des 2 entiers de m\u00eame longueur produit par l&rsquo;algorithme  de signature ( <a rel=\"noreferrer noopener\" href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc8152#section-8.1\" target=\"_blank\">document<\/a>). Ces entiers sont nomm\u00e9s R et S. Extrait :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"634\" height=\"405\" src=\"http:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/11\/COSE_ECDA_signature.png\" alt=\"\" class=\"wp-image-2927\" srcset=\"https:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/11\/COSE_ECDA_signature.png 634w, https:\/\/blogperso.union31.fr\/wp-content\/uploads\/2021\/11\/COSE_ECDA_signature-300x192.png 300w\" sizes=\"auto, (max-width: 634px) 100vw, 634px\" \/><\/figure>\n\n\n\n<p>Certains \u00e9voquent que ce type de signature correspond au format P1363.<\/p>\n\n\n\n<p>On remarque \u00e9galement (en dessous du bloc orange) que la taille des chiffres R et S est d\u00e9termin\u00e9e en fonction de la taille de la clef publique. Ainsi pour une clef de 256bytes alors la taille de la signature sera de 64 octets (R et S respectivement sur 32 octets).<\/p>\n\n\n\n<p>Ainsi dans le QR-Code la taille de la signature fait 64 bytes ce qui correspond au principe \u00e9nonc\u00e9 juste au dessus.<\/p>\n\n\n\n<p>Mais pourquoi aller dans ce niveau de d\u00e9tail ? Parce que OpenSSL ne comprend pas ce format de signature. Il utilise \u00e0 la place le format DER. Donc pour passer du format initial  au format DER il faut savoir extraire R et S pour g\u00e9n\u00e9rer une fichier signature au format DER ( <a rel=\"noreferrer noopener\" href=\"https:\/\/www.itu.int\/ITU-T\/studygroups\/com17\/languages\/X.690-0207.pdf\" target=\"_blank\">lien vers sp\u00e9cification<\/a> (ITU-T X.690) et <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/X.690\" target=\"_blank\">code des types sur wikipedia<\/a> et <a rel=\"noreferrer noopener\" href=\"https:\/\/docs.microsoft.com\/fr-fr\/windows\/win32\/seccertenroll\/about-encoded-tag-bytes\" target=\"_blank\">autre lien vers \u00b5soft<\/a>).<\/p>\n\n\n\n<p>Nous allons maintenant voir en d\u00e9tail comment cr\u00e9er un fichier de signature \u00e9quivalent (format DER) et utilisable par OpenSSL.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"V32_Creation_dun_fichier_de_signature_lisible_par_Openssl_format_DER\"><\/span>V.3.2 Cr\u00e9ation d&rsquo;un fichier de signature lisible par Openssl (format DER)<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>La signature renseign\u00e9e dans le QR-CODE est la suivante :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">FA3865EFAFEF8BB1554498C2FF11010558265E2B7780742587AA02342F3DD83AADE86C03D267DF0C338452C7C81714F2379E6CFF58CF0F5B4D0CD50EBEBCCE6E<\/code><\/pre>\n\n\n\n<p>Elle est compos\u00e9e de 2 chiffres (signatures), not\u00e9es respectivement R et S. Elles sont de tailles identiques et simplement concat\u00e9n\u00e9es. Donc les valeurs R et S sont :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">R : FA3865EFAFEF8BB1554498C2FF11010558265E2B7780742587AA02342F3DD83A\nS : ADE86C03D267DF0C338452C7C81714F2379E6CFF58CF0F5B4D0CD50EBEBCCE6E<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>Dans le format DER la structure binaire \u00e0 cr\u00e9er sera du type suivant :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">Type de donn\u00e9es               | Valeur HEX | Commentaires\n------------------------------------------------------------------------------------------------------------------------\nType_de_structure             | 30         |  indique que c'est une s\u00e9quence ...\n  Longueur totale             | 44         |  longueur de ce qui suit (calcul\u00e9 \u00e0 la fin ...)\n    Type_de_donn\u00e9s            | 02         |  le type est \"Integer\" \n     Longueur de_la_donn\u00e9e    | 20         |  taille de la valeur qui suit (20 en hex = 32 en d\u00e9cimal)\n       Valeur_de_la_donn\u00e9e    | FA3865EFAFEF8BB1554498C2FF11010558265E2B7780742587AA02342F3DD83A           |  valeur R\n    Type_de_donn\u00e9es           | 02         |   le type est \"Integer\"\n      Longueur_de_la_donn\u00e9e   | 20         |   taille de la valeur qui suit\n       Valeur_de_la_donn\u00e9e    | ADE86C03D267DF0C338452C7C81714F2379E6CFF58CF0F5B4D0CD50EBEBCCE6E           |  valeur S\n<\/code><\/pre>\n\n\n\n<p>Pour le calcul de la longueur totale, il est effectu\u00e9e de la mani\u00e8re suivante : <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">Champs                  taille\n--------------------------------------------------------------\nType de donn\u00e9es       : 1 octet\nLongueur de la donn\u00e9e : 1 octet\nla donn\u00e9e             : 32 octets\n\nType de donn\u00e9es       : 1 octet\nLongueur de la donn\u00e9e : 1 octet\nla donn\u00e9e             : 32 octets\n\nSoit au total         : 68 octets --&gt; soit 44 en Hexad\u00e9cimal  :)\n<\/code><\/pre>\n\n\n\n<p>Donc au final la signature au format DER sera le contenu suivant :<\/p>\n\n\n\n<p><span class=\"has-inline-color has-vivid-red-color\">30<\/span><span class=\"has-inline-color has-luminous-vivid-amber-color\">44<\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">02<\/span><span class=\"has-inline-color has-vivid-purple-color\">20<\/span><strong>FA3865EFAFEF8BB1554498C2FF11010558265E2B7780742587AA02342F3DD83A<\/strong><span class=\"has-inline-color has-vivid-green-cyan-color\">02<\/span><span class=\"has-inline-color has-vivid-purple-color\">20<\/span><strong>ADE86C03D267DF0C338452C7C81714F2379E6CFF58CF0F5B4D0CD50EBEBCCE6E<\/strong><\/p>\n\n\n\n<p>Pour cr\u00e9er le fichier on utilisera la commande suivante :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">echo -n \"30440220FA3865EFAFEF8BB1554498C2FF11010558265E2B7780742587AA02342F3DD83A0220ADE86C03D267DF0C338452C7C81714F2379E6CFF58CF0F5B4D0CD50EBEBCCE6E\" | xxd -r -p &gt; signature.der<\/code><\/pre>\n\n\n\n<p>Pour v\u00e9rifier le fichier :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">openssl asn1parse -in signature.der -inform DER\n\n    0:d=0  hl=2 l=  68 cons: SEQUENCE          \n    2:d=1  hl=2 l=  32 prim: INTEGER           :-05C79A105010744EAABB673D00EEFEFAA7D9A1D4887F8BDA7855FDCBD0C227C6\n   36:d=1  hl=2 l=  32 prim: INTEGER           :-521793FC2D9820F3CC7BAD3837E8EB0DC8619300A730F0A4B2F32AF141433192<\/code><\/pre>\n\n\n\n<p>Et cela ne fonctionne pas  \ud83d\ude41 \ud83d\ude41 \ud83d\ude41 Nous ne retrouvons pas nos clefs initiales et de plus elles sont n\u00e9gatives &#8230;<\/p>\n\n\n\n<p>En effet dans certains cas il faut ajouter un 00 devant les chiffres R et S.  Le format DER utilise le principe du compl\u00e9ment \u00e0 2 pour les chiffres entiers. Dans notre cas les r\u00e9sultats R et S sont des chiffres positifs. En revanche R commence par FA&#8230; et S par AD&#8230; ce qui en binaire repr\u00e9sente respectivement <strong>1<\/strong>1111010 et <strong>1<\/strong>0101101. Au format DER et comme le premier bit est \u00e0 1, ces chiffres seront consid\u00e9r\u00e9s comme n\u00e9gatif. Il faut donc ajouter un 0 devant soit 00 en hexad\u00e9cimal.<\/p>\n\n\n\n<p>Donc notre nouvelle signature comprenant le recalcul des tailles sera :<\/p>\n\n\n\n<p><span class=\"has-inline-color has-vivid-red-color\">30<\/span><span class=\"has-inline-color has-luminous-vivid-amber-color\">46<\/span><span class=\"has-inline-color has-vivid-green-cyan-color\">02<\/span><span class=\"has-inline-color has-vivid-purple-color\">21<\/span><strong><span class=\"has-inline-color has-vivid-cyan-blue-color\">00<\/span><\/strong>fa3865efafef8bb1554498c2ff11010558265e2b7780742587aa02342f3dd83a<span class=\"has-inline-color has-vivid-green-cyan-color\">02<\/span><span class=\"has-inline-color has-vivid-purple-color\">21<\/span><strong><span class=\"has-inline-color has-vivid-cyan-blue-color\">00<\/span><\/strong>ade86c03d267df0c338452c7c81714f2379e6cff58cf0f5b4d0cd50ebebcce6e<\/p>\n\n\n\n<p>Ainsi la commande shell pour g\u00e9n\u00e9rer le nouveau fichier de signature :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">echo -n \"3046022100fa3865efafef8bb1554498c2ff11010558265e2b7780742587aa02342f3dd83a022100ade86c03d267df0c338452c7c81714f2379e6cff58cf0f5b4d0cd50ebebcce6e\" | xxd -r -p &gt; signature.der<\/code><\/pre>\n\n\n\n<p>On v\u00e9rifie :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">openssl asn1parse -in signature2.der -inform DER\n\n    0:d=0  hl=2 l=  70 cons: SEQUENCE          \n    2:d=1  hl=2 l=  33 prim: INTEGER           :FA3865EFAFEF8BB1554498C2FF11010558265E2B7780742587AA02342F3DD83A\n   37:d=1  hl=2 l=  33 prim: INTEGER           :ADE86C03D267DF0C338452C7C81714F2379E6CFF58CF0F5B4D0CD50EBEBCCE6E\n<\/code><\/pre>\n\n\n\n<p>Et l\u00e0 c&rsquo;est bon, nous retrouvons les valeurs R et S au format DER \ud83d\ude42 ainsi qu&rsquo;un fichier de signature compr\u00e9hensible par OpenSSL.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"V4_Donnees_a_valider\"><\/span>V.4 Donn\u00e9es \u00e0 valider<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Nous entrons dans la derni\u00e8re \u00e9tape avant de v\u00e9rifier le QR-Code : la donn\u00e9e \u00e0 valider. On pourrait croire que le contenu du CBOR (payload) serait suffisant. Mais non, d&rsquo;apr\u00e8s les sp\u00e9cifications du COSE (<a rel=\"noreferrer noopener\" href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc8152#section-4.4\" target=\"_blank\">lien<\/a>) la v\u00e9rification se fait avec une structure <strong>CBOR sp\u00e9cifique<\/strong> (nomm\u00e9e Sig_Structure) dont la structure doit \u00eatre la suivante :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">   Sig_structure = [\n       context : \"Signature\" \/ \"Signature1\" \/ \"CounterSignature\",    --&gt; vu le type de COSE se sera Signature1\n       body_protected : empty_or_serialized_map,                     --&gt; le header du QR-COde\n       ? sign_protected : empty_or_serialized_map,                   --&gt; rien\n       external_aad : bstr,                                          --&gt; champ non utilis\u00e9 dans le COSE, donc valeur vide\n       payload : bstr                                                --&gt; le payload ou CBOR \n   ]<\/code><\/pre>\n\n\n\n<p>Ainsi notre CBOR sp\u00e9cifique sera de la forme et avec le contenu suivant :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">[\n    \"Signature1\",\n    h'A2012604487C62EEBE0EA7E709',  \n    h'',\n  h'A40164434E414D041A6488E6E0061A60FC5959390103A101A4617681AA626369781D75726E3A757663693A30313A46523A4B564A5059574D5342314256233862636F62465262646E016264746A323032312D30372D323462697364434E414D626D616D4F52472D313030303330323135626D706C45552F312F32302F313532386273640162746769383430353339303036627670674A30374258303363646F626A313937362D31322D3237636E616DA462666E6548454E525962676E6658415649455263666E746548454E525963676E74665841564945526376657265312E332E30' \n]<\/code><\/pre>\n\n\n\n<p>En utilisant un <a rel=\"noreferrer noopener\" href=\"https:\/\/cbor.me\/\" target=\"_blank\">outil en ligne <\/a>nous re-construisons le CBOR binaire \u00e0 partir du tableau \u00ab\u00a0Sig_structure\u00a0\u00bb renseign\u00e9. Ce qui nous donne le r\u00e9sultat ci-dessus : <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">846A5369676E6174757265314DA2012604487C62EEBE0EA7E7094058E2A40164434E414D041A6488E6E0061A60FC5959390103A101A4617681AA626369781D75726E3A757663693A30313A46523A4B564A5059574D5342314256233862636F62465262646E016264746A323032312D30372D323462697364434E414D626D616D4F52472D313030303330323135626D706C45552F312F32302F313532386273640162746769383430353339303036627670674A30374258303363646F626A313937362D31322D3237636E616DA462666E6548454E525962676E6658415649455263666E746548454E525963676E74665841564945526376657265312E332E30<\/code><\/pre>\n\n\n\n<p>Enfin, nous pouvons maintenant cr\u00e9er ce fichier en shell  :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">echo \"846A5369676E6174757265314DA2012604487C62EEBE0EA7E7094058E2A40164434E414D041A6488E6E0061A60FC5959390103A101A4617681AA626369781D75726E3A757663693A30313A46523A4B564A5059574D5342314256233862636F62465262646E016264746A323032312D30372D323462697364434E414D626D616D4F52472D313030303330323135626D706C45552F312F32302F313532386273640162746769383430353339303036627670674A30374258303363646F626A313937362D31322D3237636E616DA462666E6548454E525962676E6658415649455263666E746548454E525963676E74665841564945526376657265312E332E30\" | xxd -r -p &gt; data.bin<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"V5_Verification_avec_OpenSSL\"><\/span>V.5 V\u00e9rification (avec OpenSSL)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>A ce stade nous avons tout ce qu&rsquo;il faut pour effectuer la v\u00e9rification (int\u00e9grit\u00e9) du QR-CODE, c&rsquo;est \u00e0 dire :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>la clef publique ;<\/li><li>la signature au format DER ;<\/li><li>la donn\u00e9e \u00e0 v\u00e9rifier (CBOR sp\u00e9cifique) ;<\/li><\/ul>\n\n\n\n<p>Nous pouvons maintenant lancer cette v\u00e9rification du QRCODE en utilisant l&rsquo;outil OPENSSL en shell :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">openssl dgst -sha256 -verify public_key.pem -signature signature.der data.bin\nVerified OK\n<\/code><\/pre>\n\n\n\n<p>Et, apr\u00e8s tout ce labeur, nous remarqons que le contenu du QR-Code est bien int\u00e8gre (non modifi\u00e9) !<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"V6_Ressources\"><\/span>V.6 Ressources<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Ci-dessous les ressources qui ont permis de comprendre la partie v\u00e9rification du QR-Code<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>site expliquant dir KID key Identification pr\u00e9sent dans le CBOR vers la clef publique<ul><li>http:\/\/www.corentindupont.info\/blog\/posts\/Programming\/2021-08-13-GreenPass.html<\/li><\/ul><\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"VI_Fin\"><\/span>VI Fin<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"VI1_Constat_simple\"><\/span>VI.1 Constat simple<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Nous pouvons maintenant voir pr\u00e9cis\u00e9ment ce que comporte \u00e0 ce jour ce type de QR-CODE. Bref peu d&rsquo;informations et juste le n\u00e9cessaire pour dire si une personne (nom, pr\u00e9nom et date de naissance) est vaccin\u00e9e ou pas (par qui et quel type de vaccin).<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"VI2_Modification_du_JSON_et_creation_dun_autre_QR-Code\"><\/span>VI.2 Modification du JSON et cr\u00e9ation d&rsquo;un autre QR-Code<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Mais que se passe-t-il si on modifie une valeur et que l&rsquo;on applique le process inverse (en gardant les informations initiales de la signature et de l&rsquo;ent\u00eate prot\u00e9g\u00e9e) ? Comme par exemple changer le nom. H\u00e9 bien, avec l&rsquo;application \u00ab\u00a0Tous anti covid verif\u00a0\u00bb, le QR-CODE est d\u00e9clar\u00e9 invalide. En revanche l&rsquo;application affiche le nom, pr\u00e9nom et date de naissance indiqu\u00e9s dans le QR-CODE modifi\u00e9. C&rsquo;est rassurant car l&rsquo;application v\u00e9rifie la signature du QR-Code qui est fausse pour ce cas.<\/p>\n\n\n\n<p>Ci-dessous un exemple pour g\u00e9n\u00e9rer un QR-CODE :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">cat final_modif_COSE_HEX_compress_base45_HC1.txt | <strong><span class=\"has-inline-color has-vivid-cyan-blue-color\">qrencode -o qr_code.png<\/span><\/strong>    # G\u00e9n\u00e8re l'image d'un QR-Code \u00e0 partir de donn\u00e9es binaires\ndisplay qr_code.png  # Affiche le QR-CODE<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"VI3_Mais_peut-on_creer_un_vraifaux_QR-CODE\"><\/span>VI.3 Mais peut-on cr\u00e9er un vrai\/faux QR-CODE ? <span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Oui dans l&rsquo;absolu et non ou tr\u00e8s difficile en pratique. L&rsquo;application \u00ab\u00a0Tous anti-covid v\u00e9rif\u00a0\u00bb utilise une clef publique pour v\u00e9rifier la signature car cette derni\u00e8re ne communique pas sur le r\u00e9seau d&rsquo;apr\u00e8s les informations donn\u00e9es sur l&rsquo;appli (\u00e0 v\u00e9rifier&#8230;). Elle est donc autonome pour v\u00e9rifier le QR-Code. Mais la clef publique ne permet pas de g\u00e9n\u00e9rer une signature, juste de la v\u00e9rifier. Il faut une clef priv\u00e9e pour cela. Le processus pour retrouver la clef priv\u00e9e peut \u00eatre tr\u00e8s (tr\u00e8s) long mais pas impossible en soi&#8230; Par contre pour r\u00e9cup\u00e9rer la clef publique, <s>ce serait assez facile en r\u00e9cup\u00e9rant l&rsquo;APK de l&rsquo;application android<\/s> elle est disponible sur Internet (cf. au dessus) et pourquoi pas <s>voir comment<\/s> faire la v\u00e9rification de la signature soi-m\u00eame.<\/p>\n\n\n\n<p>Dans le pire des cas, on pourrait imaginer que des tests compl\u00e9mentaires soient effectu\u00e9s avec le num\u00e9ro unique du certificat. Il suffirait ensuite de comparer ce num\u00e9ro avec le nom, pr\u00e9nom et date de naissance de l&rsquo;individu. Et l\u00e0, la supercherie pourra \u00eatre d\u00e9tect\u00e9e mais cela n\u00e9cessite une connexion sur un serveur d\u00e9di\u00e9. Il semble que ce ne soit pas le cas aujourd&rsquo;hui avec l&rsquo;application fran\u00e7aise mais c&rsquo;est tout \u00e0 fait envisageable demain si le besoin s&rsquo;en faisait sentir et ce de mani\u00e8re relativement simple. Peut \u00eatre que d&rsquo;autres applications europ\u00e9ennes font cette v\u00e9rification&#8230; C&rsquo;est peut \u00eatre fait avec l&rsquo;application \u00ab\u00a0Tous anti-covid\u00a0\u00bb. Les sources (une partie) viennent d&rsquo;\u00eatre publi\u00e9es sur le <a rel=\"noreferrer noopener\" href=\"https:\/\/gitlab.inria.fr\/stopcovid19\/accueil\" target=\"_blank\">gitlab de l&rsquo;Inria<\/a> et son \u00e9tude pourra infirmer ou confirmer ce point.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"VI4_Donnees_en_clair_pas_chiffrees\"><\/span>VI.4 Donn\u00e9es en clair, pas chiffr\u00e9es ?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Pour ma part, en d\u00e9couvrant les objets binaires CBOR et surtout COSE, on remarque que les informations auraient pu \u00eatre chiffr\u00e9es, ce qui n&rsquo;est pas le cas aujourd&rsquo;hui. Or, dans le cadre de protection des donn\u00e9es des individus et au regard des informations de type m\u00e9dical cela aurait \u00e9t\u00e9 s\u00fbrement mieux. Est-ce li\u00e9 \u00e0 la limitation du nombre de caract\u00e8res possibles dans le QR-Code ou \u00e0 la complexit\u00e9 organisationnelle pour mettre en place un outil plus technique utilisable par plusieurs de type de population afin qu&rsquo;elles puissent v\u00e9rifier le QR-Code (ex : restaurateur, cin\u00e9mas, etc.) ? Cette derni\u00e8re hypoth\u00e8se semble plus probable. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"VI5_Lapplication_%C2%AB_TousAntiCovid_verif_%C2%BB\"><\/span>VI.5 L&rsquo;application \u00ab\u00a0TousAntiCovid verif\u00a0\u00bb<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Au t\u00e9l\u00e9chargement de l&rsquo;application il est stipul\u00e9 que \u00ab\u00a0<em>L&rsquo;usage de l&rsquo;application TousAntiCovid est r\u00e9serv\u00e9 aux personnes habilit\u00e9es et services autoris\u00e9s dans le cadre de la <a rel=\"noreferrer noopener\" href=\"https:\/\/www.legifrance.gouv.fr\/loda\/id\/JORFTEXT000043567200\/2021-08-06\/\" target=\"_blank\">loi n\u00b02021-689<\/a> [&#8230;]<\/em>\u00ab\u00a0. Et que si l&rsquo;on est pas \u00e9ligible \u00e0 l&rsquo;utilisation  de cette application on encoure des sanctions &#8230;<\/p>\n\n\n\n<p>Pour \u00eatre plus pr\u00e9cis, l&rsquo;application n&rsquo;est pas cit\u00e9e dans la loi. En revanche il est stipul\u00e9 dans l&rsquo;article 1 : <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>\u00ab\u00a0B. &#8211; La pr\u00e9sentation du r\u00e9sultat d&rsquo;un examen de d\u00e9pistage virologique ne concluant pas \u00e0 une contamination par la covid-19, d&rsquo;un justificatif de statut vaccinal concernant la covid-19 ou d&rsquo;un certificat de r\u00e9tablissement \u00e0 la suite d&rsquo;une contamination par la covid-19 dans les cas pr\u00e9vus au A du pr\u00e9sent II peut se faire sur papier ou sous format num\u00e9rique. La pr\u00e9sentation, sur papier ou sous format num\u00e9rique, des documents mentionn\u00e9s au premier alin\u00e9a du pr\u00e9sent B est r\u00e9alis\u00e9e sous une forme ne permettant pas aux personnes habilit\u00e9es ou aux services autoris\u00e9s \u00e0 en assurer le contr\u00f4le de conna\u00eetre la nature du document ni les donn\u00e9es qu&rsquo;il contient.\u00a0\u00bb<\/li><li>\u00ab\u00a0<em>C. &#8211; <span class=\"has-inline-color has-vivid-green-cyan-color\">Les personnes habilit\u00e9es<\/span> et nomm\u00e9ment d\u00e9sign\u00e9es et les services <span class=\"has-inline-color has-vivid-green-cyan-color\">autoris\u00e9s \u00e0 contr\u00f4ler les documents <\/span>mentionn\u00e9s aux 1\u00b0 et 2\u00b0 du A pour les soci\u00e9t\u00e9s de transport et les lieux, \u00e9tablissements ou \u00e9v\u00e9nements concern\u00e9s <strong><span class=\"has-inline-color has-vivid-green-cyan-color\">ne peuvent exiger leur pr\u00e9sentation que sous les formes pr\u00e9vues au second alin\u00e9a du B et ne sont pas autoris\u00e9s \u00e0 les conserver ou \u00e0 les r\u00e9utiliser \u00e0 d&rsquo;autres fins<\/span><\/strong>.<\/em> <strong><span class=\"has-inline-color has-luminous-vivid-orange-color\">Le fait de conserver les documents mentionn\u00e9s aux 1\u00b0 et 2\u00b0 du A dans le cadre du processus de v\u00e9rification ou de les r\u00e9utiliser \u00e0 d&rsquo;autres fins <\/span><\/strong><span class=\"has-inline-color has-luminous-vivid-orange-color\">est puni d&rsquo;un an d&#8217;emprisonnement et de 45 000 \u20ac d&rsquo;amende.<\/span>\u00ab\u00a0<\/li><li>\u00ab\u00a0D. &#8211; <span class=\"has-inline-color has-vivid-green-cyan-color\">Hors les cas pr\u00e9vus aux 1\u00b0 et 2\u00b0 du A, <\/span><strong><span class=\"has-inline-color has-vivid-green-cyan-color\">nul ne peut exiger d&rsquo;une personne la pr\u00e9sentation d&rsquo;un r\u00e9sultat d&rsquo;un examen de d\u00e9pistage virologique<\/span><\/strong> ne concluant pas \u00e0 une contamination par la covid-19, d&rsquo;un justificatif de statut vaccinal concernant la covid-19 ou d&rsquo;un certificat de r\u00e9tablissement \u00e0 la suite d&rsquo;une contamination par la covid-19. <span class=\"has-inline-color has-luminous-vivid-orange-color\">Est puni <\/span>d&rsquo;un an d&#8217;emprisonnement et de 45 000 \u20ac d&rsquo;amende <span class=\"has-inline-color has-luminous-vivid-orange-color\">le fait d&rsquo;exiger la pr\u00e9sentation des documents mentionn\u00e9s au premier alin\u00e9a du pr\u00e9sent D<\/span> pour l&rsquo;acc\u00e8s \u00e0 d&rsquo;autres lieux, \u00e9tablissements ou \u00e9v\u00e9nements que ceux mentionn\u00e9s au 2\u00b0 du A.\u00a0\u00bb<\/li><\/ul>\n\n\n\n<p>Donc nous pouvons utiliser l&rsquo;application pour lire son propre QR-code, pas ceux des autres !<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>L&rsquo;objectif est de voir pas \u00e0 pas comment sont stock\u00e9es et quelles donn\u00e9es sont pr\u00e9sentes dans un QR-CODE d\u00e9di\u00e9 au passe sanitaire. Pour cela nous utiliserons une plateforme Linux et lancerons quelques commandes Shell afin de voir toutes les \u00e9tapes<\/p>\n","protected":false},"author":1,"featured_media":2947,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-2559","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-_autres"],"_links":{"self":[{"href":"https:\/\/blogperso.union31.fr\/index.php?rest_route=\/wp\/v2\/posts\/2559","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogperso.union31.fr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogperso.union31.fr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogperso.union31.fr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blogperso.union31.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2559"}],"version-history":[{"count":225,"href":"https:\/\/blogperso.union31.fr\/index.php?rest_route=\/wp\/v2\/posts\/2559\/revisions"}],"predecessor-version":[{"id":2971,"href":"https:\/\/blogperso.union31.fr\/index.php?rest_route=\/wp\/v2\/posts\/2559\/revisions\/2971"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogperso.union31.fr\/index.php?rest_route=\/wp\/v2\/media\/2947"}],"wp:attachment":[{"href":"https:\/\/blogperso.union31.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2559"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogperso.union31.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2559"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogperso.union31.fr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2559"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}