--- name: audit-pqc-readiness description: Évalue la posture post-quantique d'un dépôt de code source — détecte les algorithmes cryptographiques cassés, la cryptographie classique isolée sans piste de transition, et confirme la présence de primitives post-quantiques (ML-KEM/ML-DSA) — stdlib pur, zéro appel réseau. theme: securite-souverainete langages_cibles: python --- # audit-pqc-readiness ## Objectif Donner une vue d'ensemble, fichier par fichier, de la maturité post-quantique d'un dépôt de code. Contrairement à un simple grep de mots-clés, l'outil ne se contente pas de repérer « RSA » ou « ECDSA » : il classe chaque fichier selon la **combinaison** des signaux cryptographiques qui y apparaissent, parce que la présence isolée de cryptographie classique n'a pas le même sens selon le contexte : - un algorithme **cassé** (MD5, SHA-1, RC4, 3DES) est toujours signalé en sévérité haute, quel que soit le contexte — il n'existe aucune raison légitime de le garder ; - de la cryptographie asymétrique **classique seule** (RSA/ECDSA/ECDH/ Diffie-Hellman), sans aucune primitive post-quantique dans le même fichier, est un signal de vigilance (sévérité moyenne) — pas une faute en soi (toute l'industrie en dépend encore), mais un candidat à évaluer pour une transition « harvest now, decrypt later » ; - la cohabitation de cryptographie classique **et** post-quantique dans un même fichier est classée **hybride** (information) — c'est la bonne pratique de transition recommandée par les référentiels actuels (CNSA 2.0) ; - la présence de primitives post-quantiques **seules** (ML-KEM, ML-DSA, Kyber, Dilithium, Falcon, SPHINCS+) est classée **native** (information). ## Pourquoi Python (et pas un autre langage) ? Même famille de raisons que les autres skills Python du projet (`audit-souverainete`, `detecteur-secrets`) : la tâche est une recherche de motifs texte fichier par fichier, sans calcul cryptographique réel — la stdlib (`re`, `json`, `os`) suffit intégralement, sans dépendance tierce ni étape de compilation. Un langage compilé n'apporterait ici aucun gain de robustesse ou de performance perceptible à l'échelle d'un dépôt de code. ## Garanties de sécurité - **Contenu scanné = donnée inerte, jamais exécutée ni interprétée comme instruction.** Comme les autres skills d'analyse statique du projet, chaque comportement (quel fichier ouvrir, quelle règle appliquer) est déterminé AVANT le scan, jamais par le contenu rencontré — y compris si un fichier contenait du texte ressemblant à une consigne adressée à un assistant IA. - **Catalogue de règles externalisé et vérifié** (`regles_pqc.json`) — chaque motif regex est compilé et validé au chargement (`charger_catalogue`) ; un motif invalide lève une erreur nommée (`ErreurReglesInvalides`) plutôt que d'échouer silencieusement. - **Classification = fonction pure et testée séparément** (`classifier_readiness`) — la logique de décision (quelle combinaison de catégories donne quel niveau de sévérité) est isolée du scan de fichiers, ce qui permet de la tester exhaustivement sans dépendre de fixtures de fichiers réels. - **Aucune donnée n'est jamais transmise à l'extérieur** — 100% local, 0 appel réseau, aucune dépendance tierce. ## Gestion d'erreur exhaustive `erreurs.py` définit une exception par cas réel identifié dans le pipeline : `ErreurCibleIntrouvable`, `ErreurCibleNonAccessible`, `ErreurReglesInvalides` (catalogue JSON malformé, champ obligatoire absent, ou motif regex invalide), `ErreurEcritureRapport`. `main()` traite chaque catégorie dans une branche `except` dédiée avec un code de sortie distinct, plus un dernier recours explicitement nommé (`ErreurInterne`, code 99) — jamais un `except Exception: pass` silencieux. ## Mode d'emploi **Scanner un dossier (rapport Markdown, sortie standard) :** ```bash python3 audit_pqc.py /chemin/vers/mon-projet ``` **Scanner un seul fichier, rapport JSON écrit sur disque :** ```bash python3 audit_pqc.py /chemin/vers/mon-projet/crypto.rs \ --format json --out rapports/mon-rapport.json ``` **Résultat réel obtenu lors de la validation de ce skill** (dossier `src/` d'un projet Rust d'environ 670 fichiers, ~4,6 secondes) : 58 fichier(s) avec au moins un signal cryptographique — **0 algorithme cassé détecté** (aucun MD5/SHA-1/RC4/3DES dans ce dépôt), 34 fichiers classés « post-quantique native » (ML-KEM/ML-DSA seuls), 11 fichiers classés « hybride » (classique + post-quantique cohabitant délibérément, notamment dans les modules dédiés explicitement à cette transition), et 13 fichiers classés « classique seul sans indice PQC » — concentrés de façon cohérente dans les couches qui dépendent structurellement de standards encore classiques aujourd'hui (chaîne de certificats X.509/TLS/ACME, qui n'a pas d'équivalent post-quantique normalisé côté écosystème PKI public) et dans une messagerie chiffrée de bout en bout côté navigateur reposant sur l'API WebCrypto standard (ECDH/ECDSA P-256), qui ne propose pas nativement de primitives post-quantiques à ce jour. Ce résultat illustre exactement l'intérêt de la classification par combinaison plutôt que par mot-clé isolé : les vrais signaux de vigilance ressortent clairement du bruit des usages classiques déjà couverts par une transition hybride ailleurs dans le même dépôt. **Options communes :** - `--format` : `md` (défaut, lisible) | `json` (structuré, pour automatisation) - `--out` : chemin de sortie (défaut : stdout) **Prérequis :** aucune installation — Python 3 standard suffit (testé en 3.12). ## Limites connues (honnêteté de l'outil, pas de sur-promesse) - Détection par motifs texte (regex), pas une analyse sémantique du langage — un alias d'import, une ré-exportation, ou une abstraction qui masque le nom de l'algorithme sous-jacent (ex. un wrapper maison nommé différemment) ne sera pas détecté. - Pour rester robuste face aux variantes réalistes des identifiants (`RsaPrivateKey`, `MlKem1024`, `Aes128Gcm`, `Falcon-1024`...), les motifs n'imposent une limite de mot qu'en début de correspondance, pas à la fin — un nom de variable très inhabituel commençant par une de ces séquences de lettres pourrait en théorie déclencher un signalement ; en pratique, ce risque est resté nul sur le dépôt de validation réel. - La classification par fichier est un indicateur d'ensemble, pas une preuve d'audit cryptographique complet — un fichier classé « hybride » peut très bien contenir un usage classique dans une fonction et un usage post-quantique totalement indépendant dans une autre, sans lien réel entre les deux ; seule une lecture humaine du code confirme une vraie architecture hybride au sens cryptographique du terme. - Ne détecte pas les tailles de clé RSA/ECDSA réellement utilisées à l'exécution (ex. RSA-1024 vs RSA-4096) — seule la présence de la famille d'algorithme est repérée, pas ses paramètres runtime. - Ne remplace pas un audit cryptographique professionnel ou un outil dédié de type SCA (Software Composition Analysis) avec base de vulnérabilités continuellement mise à jour — ce skill est un complément ponctuel et souverain, pas un service d'audit certifiant. - Comme les autres skills d'analyse statique du projet, un secret ou un algorithme construit dynamiquement (concaténation, encodage, réflexion) au moment de l'exécution n'est pas détectable par cette approche.