perf(android): the derived key is kept in the cache
Opening from the cache derives nothing, so the key learned last session was gone and the FIRST save of every session paid the 4.5 seconds again. It now travels in the sealed blob, next to the plaintext vault and to the password that opens the container - that neighbourhood is what makes it acceptable: it exposes nothing the file does not already hold. The three parts go together or not at all. A key without its salt does not say what it fits, which makes it useless, or worse, used where it does not belong. A cache written by an earlier version carries none: LoadVault returns nil, one derivation happens, and the next write stores it. A freshly registered vault still derives once - EncryptContainer does not hand back the key it just derived. The plan records what the desktop confirmed: the two entries created on the phone imported with nothing to correct.
This commit is contained in:
@@ -665,6 +665,41 @@ téléphone qu'on voudra ensuite ouvrir sur le poste demandera un import.
|
||||
ajoute un dépôt. C'est là que la fusion revient, et elle a été évitée
|
||||
jusqu'ici pour de bonnes raisons.
|
||||
|
||||
### Vérifié : le poste reprend ce que le téléphone crée — 2026-08-21
|
||||
|
||||
Deux entrées créées sur le téléphone, puis synchronisées depuis le poste :
|
||||
importées sans rien à corriger. C'est ce qui valide `AddEntry` — la forme de
|
||||
l'entrée, l'uuid, les horodatages — autrement que par relecture du code.
|
||||
|
||||
### Le coût de la dérivation, et où il est parti
|
||||
|
||||
Ajouter une entrée prenait cinq à sept secondes. Le journal a tranché :
|
||||
`key derived in 4395 ms`. Chaque enregistrement redérivait le mot de passe
|
||||
maître pour retrouver la clé qui venait de servir.
|
||||
|
||||
Deux temps :
|
||||
|
||||
1. **La clé vit le temps de la session.** Réutilisée seulement si le conteneur
|
||||
porte le même sel et le même nombre d'itérations — le poste peut avoir
|
||||
rechiffré le sien avec un sel neuf, et une clé qui ne convient pas échoue
|
||||
sur la marque de GCM en accusant un mot de passe qui serait bon.
|
||||
2. **Elle est rangée dans le cache**, à côté du coffre en clair et du mot de
|
||||
passe qui ouvre le conteneur. C'est ce voisinage qui rend l'ajout
|
||||
acceptable : elle n'expose rien que ce fichier ne détienne déjà. Sans elle,
|
||||
le *premier* enregistrement de chaque session repayait les 4,5 s, puisque
|
||||
ouvrir depuis le cache ne dérive rien.
|
||||
|
||||
Un cache écrit par une version antérieure ne porte pas de clé : `LoadVault`
|
||||
rend `nil`, on redérive une fois, et l'écriture suivante la range.
|
||||
|
||||
Reste dérivant une fois : un coffre **fraîchement inscrit** — `EncryptContainer`
|
||||
ne rend pas la clé qu'il vient de dériver.
|
||||
|
||||
**Pas mesuré sur l'appareil** : la ligne `opened with the key already in hand`.
|
||||
Une lecture répond 304 et ne déchiffre rien ; un verrouillage jette la clé.
|
||||
Seul un enregistrement réel la montre, et le coffre de test publie vers un
|
||||
vrai dépôt.
|
||||
|
||||
### Ce qui devient facultatif
|
||||
|
||||
Sans dépôt configuré, *Sync* n'a rien à faire : les réglages du serveur
|
||||
|
||||
Reference in New Issue
Block a user