**Motivations:** - Partie connectée du skeleton accessible seulement si pairing satisfait + relais OK, avec page type skeleton (avatar, notifications). - Éviter « Aucun service disponible » : contrat présent en dur dans la page, transmis à l’iframe ; navigation évidente ou automatique vers login. - Sécuriser postMessage (origine UserWallet uniquement) ; déployer data sur le proxy et certificat data.certificator.4nkweb.com. - Vulgariser cryptographie (ECDH, AES-GCM, Schnorr, workflow, collecte signatures) ; documenter correctifs et architecture. **Root causes:** - Section connectée affichée sans vérifier pairing/relay ; possibilité de forger pairing-relay-status depuis la console. - Iframe masquée ou /login chargé avant réception du contrat → graphe vide, redirection vers /services. - Pas de contrôle d’origine sur les messages reçus ; pas de projet website-data ni config Nginx/certificat pour data. **Correctifs:** - Vérification msg.origin === USERWALLET_ORIGIN dans handleMessage (skeleton). - Si session mais pas pairingRelayStatus : afficher iframe pour réception du statut, message « Vérification du statut… ». - Contrat envoyé dès load iframe (init iframe.src = USERWALLET_ORIGIN) ; au clic « Se connecter », envoi contract + navigate-login (service, membre). - UserWallet : écoute navigate-login → navigation /login?service=&membre= ; LoginScreen avec service+membre en URL ne redirige plus vers /services, dispatch E_SELECT_SERVICE / E_SELECT_MEMBER. **Evolutions:** - Message pairing-relay-status (iframe → parent) ; canShowConnectedSection exige login + pairing OK + relay OK ; page connectée avec header avatar + icône notifications. - Skeleton : getLoginContext, sendNavigateLoginToIframe, onIframeLoad, loginRequested/iframeLoaded ; contrat envoyé avec serviceUuid, membreUuid. - UserWallet : PairingRelayStatusMessage, envoi depuis HomeScreen/LoginScreen ; type navigate-login, handleNavigateLogin dans useChannel. - Page cryptographie.html (workflow, algorithmes, collecte signatures) ; liens nav, build. - website-data (Vite, channel, config), start/service/install ; configure-nginx-proxy + Certbot pour data.certificator.4nkweb.com. - fixKnowledge (postmessage-origin, section-connectee-non-affichee) ; features (partie-connectee-pairing-relay, userwallet-iframe-key-isolation). **Pages affectées:** - website-skeleton (index, main, config, serviceContract, cryptographie, technique, membre, contrat, vite.config, README). - userwallet (HomeScreen, LoginScreen, useChannel, iframeChannel, relay, crypto, iframe, Pairing*, RelaySettings, WordInputGrid, syncUpdateGraph, specs/synthese). - website-data (nouveau), configure-nginx-proxy, docs DOMAINS_AND_PORTS README, features, fixKnowledge, userwallet features/docs.
449 lines
24 KiB
HTML
449 lines
24 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="fr">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>Cryptographie expliquée – 4NK un nouveau web</title>
|
||
<style>
|
||
* { box-sizing: border-box; }
|
||
body {
|
||
font-family: system-ui, -apple-system, sans-serif;
|
||
max-width: 900px;
|
||
margin: 0 auto;
|
||
padding: 1rem;
|
||
line-height: 1.6;
|
||
color: #333;
|
||
}
|
||
h1 { font-size: 1.5rem; margin-bottom: 1rem; color: #222; }
|
||
h2 { font-size: 1.2rem; margin-top: 1.5rem; margin-bottom: 0.5rem; color: #333; }
|
||
h3 { font-size: 1rem; margin-top: 1rem; margin-bottom: 0.35rem; font-weight: 600; }
|
||
p { margin: 0.75rem 0; }
|
||
ul, ol { margin: 0.5rem 0; padding-left: 1.5rem; }
|
||
li { margin: 0.4rem 0; }
|
||
a { color: #007bff; }
|
||
a:hover { text-decoration: underline; }
|
||
.highlight { background: #e8f4fd; padding: 1rem; border-radius: 8px; border-left: 4px solid #007bff; margin: 1rem 0; }
|
||
.info { background: #d4edda; padding: 1rem; border-radius: 8px; border-left: 4px solid #28a745; margin: 1rem 0; }
|
||
.warning { background: #fff3cd; padding: 1rem; border-radius: 8px; border-left: 4px solid #ffc107; margin: 1rem 0; }
|
||
.algo { background: #f8f9fa; padding: 1rem; border-radius: 8px; border: 1px solid #e0e0e0; margin: 1rem 0; }
|
||
.algo-title { font-weight: 700; color: #007bff; margin-bottom: 0.5rem; }
|
||
details { margin: 1rem 0; }
|
||
summary { cursor: pointer; font-weight: 600; color: #555; }
|
||
.meta { font-family: ui-monospace, monospace; font-size: 0.85rem; color: #666; background: #f5f5f5; padding: 0.2em 0.4em; border-radius: 4px; word-break: break-all; }
|
||
.workflow { background: #f5f5f5; padding: 1rem; border-radius: 8px; margin: 1rem 0; font-family: ui-monospace, monospace; font-size: 0.85rem; white-space: pre-wrap; line-height: 1.4; overflow-x: auto; }
|
||
.step { background: #fff; border: 1px solid #ddd; border-radius: 8px; padding: 1rem; margin: 0.75rem 0; }
|
||
.step-num { display: inline-block; width: 28px; height: 28px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 50%; text-align: center; line-height: 28px; font-weight: 700; margin-right: 0.75rem; font-size: 0.9rem; }
|
||
.algo-table { width: 100%; border-collapse: collapse; margin: 1rem 0; }
|
||
.algo-table th, .algo-table td { padding: 0.5rem; text-align: left; border-bottom: 1px solid #ddd; }
|
||
.algo-table th { background: #f5f5f5; font-weight: 600; }
|
||
.algo-table code { background: #f5f5f5; padding: 0.2em 0.4em; border-radius: 4px; font-size: 0.9em; }
|
||
@media (max-width: 768px) {
|
||
body { padding: 0.75rem; }
|
||
h1 { font-size: 1.25rem; }
|
||
.workflow { font-size: 0.75rem; padding: 0.75rem; }
|
||
.algo-table { font-size: 0.9rem; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<h1>Cryptographie expliquée</h1>
|
||
<p><a href="index.html">← Retour à l'accueil</a> · <a href="contrat.html">Le contrat</a> · <a href="membre.html">Qui êtes-vous ?</a> · <a href="technique.html">Réseau P2P</a></p>
|
||
|
||
<div class="highlight">
|
||
<strong>En résumé :</strong> Vos messages sont protégés par plusieurs couches de cryptographie.
|
||
Seul le destinataire peut les lire (chiffrement), et il peut vérifier que c'est bien vous qui les avez envoyés (signature).
|
||
Tout cela sans que personne ne connaisse vos clés secrètes.
|
||
</div>
|
||
|
||
<h2>Comment ça marche en simple ?</h2>
|
||
<p>
|
||
Imaginez que vous voulez envoyer une lettre secrète à un ami. Dans le monde réel, vous pourriez :
|
||
</p>
|
||
<ol>
|
||
<li><strong>Mettre la lettre dans une enveloppe fermée</strong> (chiffrement) — seul celui qui a la clé peut l'ouvrir</li>
|
||
<li><strong>Signer l'enveloppe</strong> (signature) — pour prouver que c'est bien vous qui l'avez envoyée</li>
|
||
<li><strong>Donner la clé au destinataire</strong> (échange de clé) — mais sans que personne d'autre ne puisse l'intercepter</li>
|
||
</ol>
|
||
<p>
|
||
C'est exactement ce que fait la cryptographie numérique, mais de façon <strong>mathématiquement impossible à falsifier</strong>.
|
||
</p>
|
||
|
||
<h2>Les algorithmes utilisés</h2>
|
||
<p>
|
||
Voici les « outils » cryptographiques du système. Chacun a un rôle précis :
|
||
</p>
|
||
|
||
<table class="algo-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Algorithme</th>
|
||
<th>Rôle</th>
|
||
<th>Analogie</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>SHA-256</code></td>
|
||
<td>Empreinte unique du message</td>
|
||
<td>Comme une empreinte digitale : unique et impossible à inverser</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>ECDH secp256k1</code></td>
|
||
<td>Échange de clé sécurisé</td>
|
||
<td>Comme mélanger deux couleurs en public pour créer un secret commun</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>HKDF-SHA256</code></td>
|
||
<td>Dérivation de clé</td>
|
||
<td>Transformer le secret partagé en une clé utilisable</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>AES-256-GCM</code></td>
|
||
<td>Chiffrement du message</td>
|
||
<td>Un coffre-fort numérique ultra-sécurisé</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>Schnorr secp256k1</code></td>
|
||
<td>Signature numérique</td>
|
||
<td>Votre signature manuscrite, mais impossible à falsifier</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2>Détail de chaque algorithme</h2>
|
||
|
||
<div class="algo">
|
||
<div class="algo-title">SHA-256 — L'empreinte digitale</div>
|
||
<p>
|
||
SHA-256 crée une « empreinte » unique de 64 caractères hexadécimaux (256 bits) pour n'importe quel message.
|
||
Deux messages différents auront toujours des empreintes différentes.
|
||
</p>
|
||
<ul>
|
||
<li><strong>Entrée</strong> : n'importe quel texte ou données</li>
|
||
<li><strong>Sortie</strong> : 64 caractères hexadécimaux (ex: <span class="meta">a7f3c9...</span>)</li>
|
||
<li><strong>Propriété clé</strong> : impossible de retrouver le message à partir de l'empreinte</li>
|
||
</ul>
|
||
<p><em>Usage</em> : identifier chaque message de façon unique sur le relais.</p>
|
||
</div>
|
||
|
||
<div class="algo">
|
||
<div class="algo-title">ECDH secp256k1 — Le secret partagé</div>
|
||
<p>
|
||
ECDH (Elliptic Curve Diffie-Hellman) permet à deux personnes de créer un <strong>secret commun</strong>
|
||
sans jamais l'échanger directement. C'est comme de la magie mathématique !
|
||
</p>
|
||
<div class="info">
|
||
<strong>L'analogie des couleurs :</strong> Imaginez qu'Alice et Bob veulent créer une couleur secrète.
|
||
<ul>
|
||
<li>Alice mélange une couleur publique avec sa couleur secrète → obtient « couleur A »</li>
|
||
<li>Bob mélange la même couleur publique avec sa couleur secrète → obtient « couleur B »</li>
|
||
<li>Ils échangent « couleur A » et « couleur B » (publiquement, tout le monde peut voir)</li>
|
||
<li>Alice mélange « couleur B » + sa couleur secrète → obtient la couleur finale</li>
|
||
<li>Bob mélange « couleur A » + sa couleur secrète → obtient <strong>la même couleur finale</strong></li>
|
||
</ul>
|
||
Résultat : Alice et Bob ont la même couleur secrète, sans l'avoir jamais échangée !
|
||
Un espion qui a vu « couleur A » et « couleur B » ne peut pas retrouver la couleur finale.
|
||
</div>
|
||
<ul>
|
||
<li><strong>Courbe</strong> : secp256k1 (la même que Bitcoin)</li>
|
||
<li><strong>Entrée</strong> : votre clé privée + la clé publique du destinataire</li>
|
||
<li><strong>Sortie</strong> : un secret partagé (32 octets)</li>
|
||
</ul>
|
||
<p><em>Usage</em> : créer un secret pour chiffrer les messages entre deux personnes.</p>
|
||
</div>
|
||
|
||
<div class="algo">
|
||
<div class="algo-title">HKDF-SHA256 — Le raffineur de clé</div>
|
||
<p>
|
||
HKDF (HMAC-based Key Derivation Function) transforme le secret partagé ECDH en une clé
|
||
de chiffrement de haute qualité.
|
||
</p>
|
||
<ul>
|
||
<li><strong>Entrée</strong> : le secret partagé ECDH (32 octets)</li>
|
||
<li><strong>Sortie</strong> : une clé AES-256 (32 octets) de qualité cryptographique</li>
|
||
<li><strong>Pourquoi</strong> : s'assurer que la clé est uniformément aléatoire</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="algo">
|
||
<div class="algo-title">AES-256-GCM — Le coffre-fort</div>
|
||
<p>
|
||
AES-256-GCM est l'algorithme de chiffrement qui protège le contenu du message.
|
||
Il offre à la fois la <strong>confidentialité</strong> (personne ne peut lire) et
|
||
l'<strong>intégrité</strong> (personne ne peut modifier sans qu'on le sache).
|
||
</p>
|
||
<ul>
|
||
<li><strong>Taille de clé</strong> : 256 bits (très sécurisé)</li>
|
||
<li><strong>Mode</strong> : GCM (Galois/Counter Mode) avec authentification</li>
|
||
<li><strong>IV</strong> : vecteur d'initialisation de 12 octets (différent à chaque chiffrement)</li>
|
||
<li><strong>Tag</strong> : code d'authentification de 16 octets (détecte les modifications)</li>
|
||
</ul>
|
||
<p><em>Usage</em> : chiffrer le message pour que seul le destinataire puisse le lire.</p>
|
||
</div>
|
||
|
||
<div class="algo">
|
||
<div class="algo-title">Schnorr secp256k1 — La signature</div>
|
||
<p>
|
||
La signature Schnorr prouve que vous êtes bien l'auteur du message, sans révéler votre clé privée.
|
||
Elle est <strong>plus efficace</strong> et <strong>plus simple</strong> que les signatures ECDSA traditionnelles.
|
||
</p>
|
||
<ul>
|
||
<li><strong>Entrée</strong> : le hash du message + votre clé privée</li>
|
||
<li><strong>Sortie</strong> : une signature de 64 octets (128 caractères hex)</li>
|
||
<li><strong>Vérification</strong> : n'importe qui peut vérifier avec votre clé publique</li>
|
||
</ul>
|
||
<div class="warning">
|
||
<strong>Important :</strong> La signature prouve que vous avez signé, mais elle ne révèle
|
||
jamais votre clé privée. Même en voyant 1000 de vos signatures, personne ne peut
|
||
retrouver votre clé secrète.
|
||
</div>
|
||
</div>
|
||
|
||
<h2>Le workflow complet</h2>
|
||
<p>
|
||
Voici ce qui se passe quand vous envoyez un message sécurisé, étape par étape :
|
||
</p>
|
||
|
||
<h3>Phase 1 : Préparation</h3>
|
||
<div class="step">
|
||
<span class="step-num">1</span>
|
||
<strong>Création du message</strong><br>
|
||
Votre message est structuré avec : les données, un horodatage, un identifiant unique (UUID), et les règles de validation.
|
||
</div>
|
||
<div class="step">
|
||
<span class="step-num">2</span>
|
||
<strong>Calcul de l'empreinte (hash)</strong><br>
|
||
<span class="meta">Message → SHA-256 → Hash (64 caractères)</span><br>
|
||
Cette empreinte unique identifie le message sur le réseau.
|
||
</div>
|
||
<div class="step">
|
||
<span class="step-num">3</span>
|
||
<strong>Génération du nonce</strong><br>
|
||
Un nombre aléatoire unique (nonce) est créé pour éviter qu'un même message soit rejoué.
|
||
</div>
|
||
|
||
<h3>Phase 2 : Chiffrement</h3>
|
||
<div class="step">
|
||
<span class="step-num">4</span>
|
||
<strong>Échange de clé ECDH</strong><br>
|
||
<span class="meta">Votre clé privée + Clé publique du destinataire → ECDH → Secret partagé</span><br>
|
||
Un secret commun est calculé mathématiquement, sans jamais être transmis.
|
||
</div>
|
||
<div class="step">
|
||
<span class="step-num">5</span>
|
||
<strong>Dérivation de la clé AES</strong><br>
|
||
<span class="meta">Secret partagé → HKDF-SHA256 → Clé AES-256</span><br>
|
||
Le secret est transformé en une clé de chiffrement de qualité.
|
||
</div>
|
||
<div class="step">
|
||
<span class="step-num">6</span>
|
||
<strong>Chiffrement du message</strong><br>
|
||
<span class="meta">Clé AES + IV aléatoire + Message → AES-256-GCM → Message chiffré + Tag</span><br>
|
||
Le message est enfermé dans un « coffre-fort » numérique.
|
||
</div>
|
||
|
||
<h3>Phase 3 : Signature</h3>
|
||
<div class="step">
|
||
<span class="step-num">7</span>
|
||
<strong>Signature Schnorr</strong><br>
|
||
<span class="meta">Hash + Nonce + Votre clé privée → Schnorr → Signature</span><br>
|
||
Vous signez l'empreinte du message avec votre clé privée.
|
||
</div>
|
||
|
||
<h3>Phase 4 : Publication sur le relais</h3>
|
||
<div class="step">
|
||
<span class="step-num">8</span>
|
||
<strong>Envoi au relais</strong><br>
|
||
Trois éléments sont envoyés séparément :
|
||
<ul style="margin-top: 0.5rem;">
|
||
<li><strong>MsgChiffre</strong> : le message chiffré + son hash</li>
|
||
<li><strong>MsgCle</strong> : l'IV + votre clé publique (pour que le destinataire puisse déchiffrer)</li>
|
||
<li><strong>MsgSignature</strong> : votre signature + clé publique</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<h3>Phase 5 : Collecte des signatures (multi-signature)</h3>
|
||
<div class="step">
|
||
<span class="step-num">9</span>
|
||
<strong>Attente des co-signataires</strong><br>
|
||
Si le contrat exige plusieurs signatures (ex: 2 appareils sur 3), le système attend que les autres signent :
|
||
<ul style="margin-top: 0.5rem;">
|
||
<li>Interrogation du relais toutes les 2 secondes</li>
|
||
<li>Timeout après 5 minutes si signatures manquantes</li>
|
||
<li>Progression affichée (ex: "2/3 signatures")</li>
|
||
</ul>
|
||
</div>
|
||
<div class="step">
|
||
<span class="step-num">10</span>
|
||
<strong>Validation</strong><br>
|
||
Le message est validé quand :
|
||
<ul style="margin-top: 0.5rem;">
|
||
<li>Toutes les signatures requises sont présentes (cardinalité)</li>
|
||
<li>Les dépendances sont respectées (ex: "A doit signer avant B")</li>
|
||
<li>Les clés publiques correspondent aux signataires autorisés</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<h3>Phase 6 : Réception et déchiffrement</h3>
|
||
<div class="step">
|
||
<span class="step-num">11</span>
|
||
<strong>Scan des clés</strong><br>
|
||
Le destinataire interroge le relais pour récupérer les MsgCle récentes.
|
||
</div>
|
||
<div class="step">
|
||
<span class="step-num">12</span>
|
||
<strong>Récupération du message</strong><br>
|
||
Avec le hash trouvé dans la MsgCle, il récupère le message chiffré.
|
||
</div>
|
||
<div class="step">
|
||
<span class="step-num">13</span>
|
||
<strong>Déchiffrement ECDH inverse</strong><br>
|
||
<span class="meta">Sa clé privée + Clé publique de l'émetteur (df) → ECDH → Même secret partagé</span><br>
|
||
Il recalcule le même secret, puis déchiffre avec AES-GCM.
|
||
</div>
|
||
<div class="step">
|
||
<span class="step-num">14</span>
|
||
<strong>Vérification des signatures</strong><br>
|
||
Chaque signature est vérifiée avec la clé publique du signataire.
|
||
</div>
|
||
|
||
<h2>Schéma récapitulatif</h2>
|
||
<div class="workflow">┌─────────────────────────────────────────────────────────────────┐
|
||
│ ÉMETTEUR │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ Message → SHA-256 → Hash │
|
||
│ │
|
||
│ Clé privée émetteur ─┐ │
|
||
│ ├──→ ECDH → Secret partagé │
|
||
│ Clé publique dest. ──┘ │
|
||
│ │
|
||
│ Secret partagé → HKDF-SHA256 → Clé AES-256 │
|
||
│ │
|
||
│ Clé AES + IV + Message → AES-256-GCM → Message chiffré │
|
||
│ │
|
||
│ Hash + Nonce + Clé privée → Schnorr → Signature │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ RELAIS │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ POST /messages ← MsgChiffre (hash, message_chiffre) │
|
||
│ POST /keys ← MsgCle (hash, iv, df_ecdh = clé pub émett.) │
|
||
│ POST /signatures← MsgSignature (hash, signature, clé publique) │
|
||
│ │
|
||
│ ... attente des co-signatures (GET /signatures/:hash) ... │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ DESTINATAIRE │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ GET /keys?start=&end= → Liste des MsgCle récentes │
|
||
│ GET /messages/:hash → MsgChiffre │
|
||
│ GET /signatures/:hash → MsgSignature[] │
|
||
│ │
|
||
│ Clé privée dest. ────┐ │
|
||
│ ├──→ ECDH → Même secret partagé │
|
||
│ Clé publique émett. ─┘ (df_ecdh_scannable) │
|
||
│ │
|
||
│ Secret partagé → HKDF-SHA256 → Clé AES-256 │
|
||
│ │
|
||
│ Clé AES + IV + Ciphertext → AES-256-GCM → Message original │
|
||
│ │
|
||
│ Vérification : Signature + Clé publique → Schnorr verify → OK │
|
||
└─────────────────────────────────────────────────────────────────┘</div>
|
||
|
||
<h2>Pourquoi c'est sécurisé ?</h2>
|
||
|
||
<h3>Confidentialité</h3>
|
||
<ul>
|
||
<li><strong>Seul le destinataire peut lire</strong> : le secret partagé ECDH ne peut être calculé que par l'émetteur et le destinataire</li>
|
||
<li><strong>AES-256</strong> : considéré incassable avec les technologies actuelles (2²⁵⁶ combinaisons possibles)</li>
|
||
<li><strong>IV unique</strong> : même si vous envoyez le même message deux fois, le résultat chiffré sera différent</li>
|
||
</ul>
|
||
|
||
<h3>Intégrité</h3>
|
||
<ul>
|
||
<li><strong>GCM</strong> : le mode Galois/Counter détecte toute modification du message chiffré</li>
|
||
<li><strong>Hash</strong> : l'empreinte SHA-256 garantit que le message n'a pas été altéré</li>
|
||
</ul>
|
||
|
||
<h3>Authenticité</h3>
|
||
<ul>
|
||
<li><strong>Signature Schnorr</strong> : prouve mathématiquement que c'est bien vous qui avez signé</li>
|
||
<li><strong>Multi-signature</strong> : plusieurs appareils peuvent être requis pour valider</li>
|
||
<li><strong>Anti-rejeu</strong> : le nonce empêche de réutiliser une ancienne signature</li>
|
||
</ul>
|
||
|
||
<h3>Séparation des données</h3>
|
||
<ul>
|
||
<li><strong>Message, clé et signature séparés</strong> : même si quelqu'un intercepte un élément, il ne peut rien faire sans les autres</li>
|
||
<li><strong>Clé privée jamais transmise</strong> : seules les clés publiques et les signatures circulent</li>
|
||
</ul>
|
||
|
||
<details>
|
||
<summary>Détails techniques pour les développeurs</summary>
|
||
|
||
<h3>Paramètres cryptographiques</h3>
|
||
<table class="algo-table">
|
||
<tr><th>Paramètre</th><th>Valeur</th></tr>
|
||
<tr><td>Courbe elliptique</td><td>secp256k1 (256 bits)</td></tr>
|
||
<tr><td>Taille clé AES</td><td>256 bits</td></tr>
|
||
<tr><td>Taille IV (AES-GCM)</td><td>96 bits (12 octets)</td></tr>
|
||
<tr><td>Taille Tag (AES-GCM)</td><td>128 bits (16 octets)</td></tr>
|
||
<tr><td>Hash</td><td>SHA-256 (256 bits)</td></tr>
|
||
<tr><td>KDF</td><td>HKDF-SHA256</td></tr>
|
||
<tr><td>Signature</td><td>Schnorr secp256k1 (64 octets)</td></tr>
|
||
</table>
|
||
|
||
<h3>Bibliothèques utilisées</h3>
|
||
<ul>
|
||
<li><code>@noble/secp256k1</code> : ECDH, Schnorr, manipulation de clés</li>
|
||
<li><code>@noble/hashes</code> : SHA-256, HKDF</li>
|
||
<li><code>Web Crypto API</code> : AES-256-GCM (navigateur)</li>
|
||
</ul>
|
||
|
||
<h3>Format des clés</h3>
|
||
<ul>
|
||
<li><strong>Clé privée</strong> : 32 octets (64 caractères hex)</li>
|
||
<li><strong>Clé publique (compressée)</strong> : 33 octets (66 caractères hex, préfixe 02 ou 03)</li>
|
||
<li><strong>Signature Schnorr</strong> : 64 octets (128 caractères hex)</li>
|
||
</ul>
|
||
|
||
<h3>Fichiers source</h3>
|
||
<ul>
|
||
<li><code>userwallet/src/utils/encryption.ts</code> : encryptWithECDH, decryptWithECDH</li>
|
||
<li><code>userwallet/src/utils/crypto.ts</code> : signMessage, verifySignature, generateChallenge</li>
|
||
<li><code>userwallet/src/utils/relay.ts</code> : postMessageChiffre, postSignature, postKey</li>
|
||
<li><code>userwallet/src/utils/collectSignatures.ts</code> : runCollectLoop, fetchSignaturesForHash</li>
|
||
<li><code>userwallet/src/utils/loginValidation.ts</code> : hasEnoughSignatures, checkDependenciesSatisfied</li>
|
||
<li><code>service-login-verify/</code> : verifyLoginProof (côté parent)</li>
|
||
</ul>
|
||
|
||
<h3>Collecte des signatures</h3>
|
||
<table class="algo-table">
|
||
<tr><th>Constante</th><th>Valeur</th><th>Description</th></tr>
|
||
<tr><td>COLLECT_POLL_MS</td><td>2 000 ms</td><td>Intervalle entre chaque interrogation</td></tr>
|
||
<tr><td>COLLECT_TIMEOUT_MS</td><td>300 000 ms</td><td>Timeout global (5 minutes)</td></tr>
|
||
<tr><td>COLLECT_FETCH_TIMEOUT_MS</td><td>15 000 ms</td><td>Timeout par requête</td></tr>
|
||
</table>
|
||
</details>
|
||
|
||
<h2>En résumé</h2>
|
||
<div class="info">
|
||
<strong>Le système combine plusieurs couches de protection :</strong>
|
||
<ol>
|
||
<li><strong>ECDH</strong> pour créer un secret sans jamais l'échanger</li>
|
||
<li><strong>AES-256-GCM</strong> pour chiffrer le message</li>
|
||
<li><strong>Schnorr</strong> pour prouver votre identité</li>
|
||
<li><strong>SHA-256</strong> pour identifier chaque message de façon unique</li>
|
||
<li><strong>Multi-signature</strong> pour exiger plusieurs validations</li>
|
||
</ol>
|
||
Résultat : vos messages sont <strong>confidentiels</strong>, <strong>authentiques</strong> et <strong>infalsifiables</strong>.
|
||
</div>
|
||
|
||
<p><a href="index.html">← Retour à l'accueil</a> · <a href="contrat.html">Le contrat</a> · <a href="membre.html">Qui êtes-vous ?</a> · <a href="technique.html">Réseau P2P</a></p>
|
||
</body>
|
||
</html>
|