code_rotatif.py — accès temporel type authentification à deux facteurs

Bienvenue sur CFTPfr.fr Forums code_rotatif.py — accès temporel type authentification à deux facteurs

  • Ce sujet est vide.
Affichage de 1 message (sur 1 au total)
  • Auteur
    Messages
  • #300
    Mario Da Conceicao
    Maître des clés

    Nouveau composant du 01/08/2026 — code d’accès à rotation temporelle. Sert à débloquer une clé verrouillée par erreur (mauvaise manipulation, fausse alerte de detection_violation.py) et à accéder à la base pour les mises à jour côté client. Basé sur un principe standard et éprouvé (même famille que les codes Google Authenticator), pas une invention fragile.

    Principe

    Le code se calcule à partir de 3 éléments combinés :

    1. Date/heure de création du client (fixe, définie une fois)
    2. Identifiant du client (fixe)
    3. Un code spécifique choisi par toi, le créateur (fixe, secret)

    Ces 3 éléments forment une "base secrète" fixe. Le code affiché, lui, change automatiquement selon l’heure actuelle — calculé à partir de cette base + l’heure. Toi et la clé du client, ayant la même base secrète, calculez chacun de votre côté le même code au même moment, sans jamais avoir besoin de vous synchroniser en ligne.

    import hmac
    import hashlib
    import struct
    import time
    
    class CodeRotatif:
        """
        Génère un code d'accès qui change selon l'heure — même principe que
        les applications d'authentification à deux facteurs (standard TOTP,
        RFC 6238, le même que Google Authenticator). Fonctionne sans internet :
        créateur et clé client calculent le même code de leur côté, à partir
        de la même base secrète.
        """
    
        def __init__(self, date_creation_client, identifiant_client, code_specifique_createur, intervalle_secondes=1800):
            """
            date_creation_client : ex "2026-08-01T14:32:00"
            identifiant_client : identifiant unique du client
            code_specifique_createur : code secret choisi par toi pour ce client
            intervalle_secondes : durée de validité d'un code (1800 = 30 min,
                                   ajustable — plus court = plus sûr mais plus
                                   contraignant)
            """
            base = f"{date_creation_client}|{identifiant_client}|{code_specifique_createur}"
            self.cle_secrete = hashlib.sha256(base.encode("utf-8")).digest()
            self.intervalle = intervalle_secondes
    
        def _fenetre_temporelle(self, horodatage=None):
            horodatage = horodatage or time.time()
            return int(horodatage // self.intervalle)
    
        def generer_code(self, horodatage=None, longueur=8):
            """Code valide pour la fenêtre de temps actuelle."""
            fenetre = self._fenetre_temporelle(horodatage)
            message = struct.pack(">Q", fenetre)
            signature = hmac.new(self.cle_secrete, message, hashlib.sha256).hexdigest()
            return signature[:longueur].upper()
    
        def verifier_code(self, code_saisi, tolerance_fenetres=1):
            """
            Vérifie un code saisi, avec une petite tolérance de décalage
            d'horloge (une fenêtre avant/après), pour ne pas bloquer un accès
            légitime à cause de quelques minutes de décalage entre deux horloges.
            Utilise une comparaison à temps constant (hmac.compare_digest)
            pour éviter les attaques par mesure de temps de réponse.
            """
            fenetre_actuelle = self._fenetre_temporelle()
            for decalage in range(-tolerance_fenetres, tolerance_fenetres + 1):
                horodatage_test = (fenetre_actuelle + decalage) * self.intervalle
                if hmac.compare_digest(code_saisi.upper(), self.generer_code(horodatage_test)):
                    return True
            return False

    Ce que ça permet concrètement

    • Débloquer une clé verrouillée par erreur : toi, connaissant la base secrète du client, génères le code valide du moment et le lui donnes pour rétablir l’accès
    • Autoriser une mise à jour : le code du moment sert de clé d’accès à la base, cohérent avec peut_se_mettre_a_jour() dans limiteur.py
    • Clé illisible sans le bon code : ce code sert aussi de base pour chiffrer les fichiers sensibles (licence.json, config) — lecture/écriture impossibles sans repasser par le bon code du moment, ce qui répond à ta demande d’une clé "inaccessible en lecture et écriture sauf avec clé d’accès"

    Précision honnête

    Ce n’est pas une invention isolée — c’est le même principe que des systèmes utilisés à grande échelle (banques, authentification à deux facteurs), donc solide et éprouvé. Mais comme toute protection logicielle (voir le plan anti-piratage), ça reste une barrière très sérieuse, pas une garantie absolue à 100%.

Affichage de 1 message (sur 1 au total)
  • Vous devez être connecté pour répondre à ce sujet.
Retour en haut