PD-42 - Recherche deterministe chiffree (Server-Side Search)¶
1. Objectif¶
La presente specification definit, de maniere canonique, contractuelle et testable, un mecanisme de recherche deterministe sur keywords tokenises, permettant l execution de requetes cote serveur sans acces aux keywords en clair.
Le mecanisme fixe les regles de canonicalisation, de derivation de cle, d algorithme et d observabilite. La confidentialite garantie est limitee a l absence de keywords en clair cote serveur ; les fuites d egalite/frequence et d access pattern sont traitees comme hors perimetre.
Aucune implementation logicielle n est decrite dans ce document.
2. Perimetre / Hors perimetre¶
2.1 Inclus¶
- Canonicalisation deterministe des keywords (KW-CANON-01).
- Derivation de K_search par utilisateur (HKDF-SHA256, contexte
keyword_search). - Tokenisation deterministe par HMAC-SHA256 (algorithm_id
DET-HMAC-SHA256-B64T22-V1). - Indexation chiffree et recherche par egalite stricte.
- Metadonnees contractuelles (algorithm_id, canonicalization_id, k_search_scope) et observabilite des rejets.
- Stabilite des tokens pour un meme triplet algorithm_id/canonicalization_id/K_search (ou identifiant logique equivalent).
2.2 Hors perimetre¶
- Recherche plein texte (full-text search).
- Recherche floue, partielle, semantique ou par similarite.
- Classement par pertinence.
- Requetes multi-keywords (AND/OR) et scoring.
- Protection contre l analyse de frequence, les attaques par dictionnaire, et l access pattern leakage.
- Injectivite globale hors espace nominal contractuel.
Les elements hors perimetre sont explicitement non testables dans le cadre de la presente specification.
3. Definitions et identifiants normatifs¶
3.1 Definitions¶
- Keyword : chaine UTF-8 fournie par le client.
- Keyword canonique : resultat de la canonicalisation KW-CANON-01.
- Token de recherche (T_kw) : valeur deterministe produite a partir d un keyword canonique et de K_search, encodee en Base64 RFC 4648 URL-safe sans padding.
- K_master_user : cle secrete de 32 octets, propre a un utilisateur.
- K_search : cle derivee de K_master_user, reservee a la tokenisation des keywords.
- Serveur de recherche : composant qui stocke des T_kw et compare par egalite.
- Index de recherche : association d une ressource a un ensemble de T_kw ; l ajout de keywords n altere pas les T_kw existants.
- Zero-knowledge (au sens du present document) : le serveur ne recoit ni ne persiste de keyword en clair, uniquement des T_kw et metadonnees.
- Espace nominal contractuel : ensemble fini des keywords canoniques conformes a KW-CANON-01, de longueur <= keyword_max_len_bytes en octets UTF-8, composes de caracteres Unicode hors controles (Cc/Cs).
3.2 Identifiants normatifs¶
| Parametre | Valeur normative |
|---|---|
| canonicalization_id | KW-CANON-01 |
| algorithm_id | DET-HMAC-SHA256-B64T22-V1 |
| k_search_scope | USER |
| k_search_context | keyword_search |
| keyword_max_len_bytes | 256 |
4. Parametres contractuels¶
4.1 Canonicalisation KW-CANON-01¶
La canonicalisation est obligatoire a l indexation et a la recherche.
Regles : - Entree : chaine UTF-8. - Normalisation Unicode en NFC (UAX #15). - Suppression des espaces en tete et fin (Unicode White_Space). - Remplacement de toute sequence de White_Space interne par un seul U+0020. - Passage en minuscules via mappage Unicode simple (sans locale). - Rejet si la chaine resultante est vide (ERR-01). - Rejet si la chaine resultante contient un caractere de controle (categories Unicode Cc/Cs) (ERR-02). - Rejet si la longueur en octets UTF-8 depasse keyword_max_len_bytes (ERR-05).
4.2 Derivation de K_search¶
- K_master_user doit etre une cle de 32 octets.
- K_search = HKDF-SHA256(K_master_user, salt=0x00 * 32, info=
keyword_search, L=32). - Portee : USER. K_search ne doit jamais etre partagee entre utilisateurs ou tenants.
- Toute rotation de K_master_user (ou changement de k_search_context) invalide l index et impose une reindexation complete.
4.3 Tokenisation deterministe (algorithm_id DET-HMAC-SHA256-B64T22-V1)¶
- T_kw = HMAC-SHA256(K_search, keyword_canonique).
- Encodage Base64 RFC 4648 URL-safe (alphabet A-Z a-z 0-9 - _) sans padding, puis troncature aux 22 premiers caracteres.
- La longueur attendue de T_kw est de 22 caracteres.
- La comparaison de T_kw est une egalite stricte (byte-to-byte).
4.4 Metadonnees contractuelles¶
- Chaque index (ou entree stockee) est associe a algorithm_id, canonicalization_id et k_search_scope.
- Un mismatch de metadonnees entre client et serveur entraine un rejet (ERR-04).
- Ces metadonnees doivent etre observables en audit.
4.5 Injectivite conditionnelle¶
- La transformation keyword canonique -> T_kw est reputee injective dans l espace nominal contractuel.
- Toute collision entre deux keywords canoniques distincts dans cet espace constitue une non-conformite.
- En dehors de cet espace nominal, l injectivite globale n est pas garantie et est hors perimetre.
- La conformite est evaluee par verification deterministe sur un ensemble fini de cas representatifs ; l injectivite globale n est pas demontrable exhaustivement.
5. Invariants (non negociables)¶
| ID | Invariant | Justification |
|---|---|---|
| INV-01 | A keyword canonique identique, K_search et algorithm_id identiques => T_kw strictement identique | Determinisme requis |
| INV-02 | A keyword canonique different dans l espace nominal contractuel, T_kw est different (collision fonctionnelle = non conformite) | Absence de faux positifs |
| INV-03 | Le serveur ne recoit ni ne persiste de keyword en clair, uniquement T_kw et metadonnees | Zero-knowledge contractuel |
| INV-04 | K_search est isolee et derivee exclusivement de K_master_user, portee USER | Cloisonnement cryptographique |
| INV-05 | La recherche repose uniquement sur l egalite de T_kw ; le resultat correspond aux ressources associees | Testabilite et simplicite |
6. Flux nominaux¶
6.1 Indexation d un keyword¶
- Un keyword est fourni cote client.
- Le keyword est canonicalise (KW-CANON-01).
- K_search est derivee pour l utilisateur.
- T_kw est calcule selon algorithm_id.
- T_kw, algorithm_id et canonicalization_id sont transmis au serveur.
- Le serveur stocke uniquement T_kw et les metadonnees associees.
6.2 Recherche d un keyword¶
- Un keyword de recherche est fourni cote client.
- Le keyword est canonicalise (KW-CANON-01).
- K_search est derivee pour l utilisateur.
- T_kw est calcule selon algorithm_id.
- Le serveur compare les T_kw par egalite stricte et retourne l ensemble des ressources correspondantes.
- L ordre des resultats n est pas contractuel ; la reproductibilite se mesure sur l ensemble.
6.3 Diagrammes¶
6.3.1 Sequence — Indexation d un keyword (flux 6.1)¶
Le client derive K_search, tokenise le keyword et transmet uniquement le token au serveur. Le serveur ne voit jamais le keyword en clair (INV-03).
sequenceDiagram
participant U as Client
participant C as Crypto Module
participant S as Serveur de recherche
U->>C: keyword (UTF-8)
C->>C: KW-CANON-01 (NFC, trim, lowercase)
alt keyword invalide
C-->>U: Rejet ERR-01 / ERR-02 / ERR-05
end
C->>C: K_search = HKDF-SHA256(K_master_user, salt=0x00*32, info="keyword_search", L=32)
Note right of C: INV-04 — K_search isolee, portee USER
C->>C: T_kw = Base64url(HMAC-SHA256(K_search, keyword_canonique))[:22]
Note right of C: INV-01 — determinisme garanti
U->>S: T_kw + algorithm_id + canonicalization_id
Note over S: INV-03 — zero keyword en clair
S->>S: Stocke T_kw + metadonnees
S-->>U: OK (index mis a jour) 6.3.2 Sequence — Recherche par keyword (flux 6.2)¶
Le client produit le meme T_kw que lors de l indexation ; le serveur compare par egalite stricte (INV-05).
sequenceDiagram
participant U as Client
participant C as Crypto Module
participant S as Serveur de recherche
U->>C: keyword de recherche (UTF-8)
C->>C: KW-CANON-01 (NFC, trim, lowercase)
alt keyword invalide
C-->>U: Rejet ERR-01 / ERR-02 / ERR-05
end
C->>C: K_search = HKDF-SHA256(K_master_user, salt=0x00*32, info="keyword_search", L=32)
C->>C: T_kw = Base64url(HMAC-SHA256(K_search, keyword_canonique))[:22]
Note right of C: INV-01 — meme keyword => meme T_kw
U->>S: T_kw + algorithm_id + canonicalization_id
S->>S: Verification metadonnees (algorithm_id, canonicalization_id)
alt mismatch metadonnees
S-->>U: Rejet ERR-04
end
S->>S: Comparaison egalite stricte T_kw (byte-to-byte)
Note over S: INV-05 — recherche par egalite uniquement
Note over S: INV-02 — pas de collision dans l espace nominal
S-->>U: Ensemble des ressources correspondantes 6.3.3 Etat — Cycle de vie d un keyword token¶
Le token traverse trois etats : derivation cote client, stockage serveur, et invalidation lors d une rotation de cle.
stateDiagram-v2
[*] --> Canonicalise: keyword UTF-8 soumis
Canonicalise --> Rejete: ERR-01 / ERR-02 / ERR-05
Rejete --> [*]
Canonicalise --> Tokenise: KW-CANON-01 OK + HMAC-SHA256
Tokenise --> Indexe: T_kw transmis au serveur (INV-03)
Indexe --> Recherchable: Egalite stricte active (INV-05)
Recherchable --> Recherchable: Requete match (INV-01)
Recherchable --> Invalide: Rotation K_master_user ou changement algorithm_id
Invalide --> [*]: Reindexation requise (H-03) 7. Cas d erreur¶
| ID | Situation | Resultat attendu |
|---|---|---|
| ERR-01 | Keyword vide apres canonicalisation | Rejet explicite (code ERR-01) |
| ERR-02 | Keyword non canonicalisable (UTF-8 invalide, caractere de controle) | Rejet explicite (code ERR-02) |
| ERR-03 | K_search absente ou longueur invalide | Operation impossible, rejet explicite (code ERR-03) |
| ERR-04 | algorithm_id / canonicalization_id manquant ou non reconnu, ou payload non conforme (ex. keyword en clair cote serveur) | Non-conformite, rejet explicite (code ERR-04) |
| ERR-05 | Keyword canonique depasse keyword_max_len_bytes | Rejet explicite (code ERR-05) |
8. Observabilite requise¶
- T_kw stockes et associes a algorithm_id + canonicalization_id.
- Resultats de recherche (ensemble d identifiants de ressources).
- Traces de rejet contenant le code ERR-xx.
9. Criteres d acceptation (testables)¶
| ID | Critere | Observable |
|---|---|---|
| CA-01 | Meme keyword canonique + meme K_search + meme algorithm_id => T_kw identique | Egalite stricte |
| CA-02 | Keywords canoniques differents dans l espace nominal contractuel => T_kw differents | Inegalite |
| CA-03 | Aucune donnee en clair cote serveur ; toute tentative d injection est rejetee | Inspection + traces |
| CA-04 | Resultat de recherche exact et reproductible (meme ensemble) | Comparaison d ensemble |
| CA-05 | Absence de faux positifs dans l espace nominal contractuel | Zero collision fonctionnelle |
10. Hypotheses explicites¶
Les hypotheses H-04 et H-05 concernent l environnement client. Les hypotheses H-06 a H-09 concernent l usage serveur et renvoient a PD-236 pour l implementation backend.
| ID | Hypothese | Impact si faux |
|---|---|---|
| H-01 | K_master_user est une cle secrete aleatoire de 32 octets par utilisateur | Risque de compromission/collisions |
| H-02 | Le client applique KW-CANON-01 avant toute tokenisation | Resultats incoherents |
| H-03 | algorithm_id et canonicalization_id restent stables pour un index ; changement => reindexation | Index incoherent |
| H-04 | Bibliotheque crypto conforme (HKDF, HMAC-SHA256) | Tokens incorrects |
| H-05 | Implementation Unicode NFC disponible et conforme UAX #15 | Canonicalisation incorrecte |
| H-06 | Base64 URL-safe sans padding disponible | Format T_kw incorrect |
| H-07 | Comparaison byte-to-byte sans normalisation cote serveur | Faux positifs/negatifs |
| H-08 | Stockage supporte un format fixe pour T_kw (22 caracteres pour DET-HMAC-SHA256-B64T22-V1) | Troncature |
| H-09 | k_search_scope USER derive d un contexte d authentification serveur valide ; le client ne peut pas usurper l identite d un autre utilisateur | Violation de l isolation K_search (INV-04) |
References¶
- Epic : PD-189 CRYPTO
- JIRA : PD-42
- Dependance : PD-236 - Recherche backend par tokens deterministes
- Repos concernes : backend / client