feat(android): measure the native PBKDF2 against the vector instead of guessing

The Pascal loop takes 1736 ms on a desktop CPU, so several seconds on a phone - too slow for every unlock. SecretKeyFactory is native and roughly an order of magnitude faster, but PBEKeySpec takes a char[] and the provider picks the encoding, which was the reason for avoiding it.

The non-ASCII vector settles it on a real device: same key means the provider uses UTF-8 and we adopt it; a different key means the Pascal implementation stays. DecryptContainer keeps using the Pascal one until that measurement says otherwise.
This commit is contained in:
r-zakarya
2026-08-14 18:33:56 +01:00
parent 386bf74a2a
commit c607e26c4a
3 changed files with 109 additions and 0 deletions
+25
View File
@@ -118,6 +118,31 @@ begin
Exit; // inutile de tester AES avec une mauvaise cle
end;
// ---- Etage 1bis : le PBKDF2 natif d'Android ----------------------
// Question ouverte, tranchee ici plutot que supposee : PBEKeySpec
// prend un char[] et le fournisseur choisit l'encodage. S'il donne la
// MEME cle sur ce mot de passe non-ASCII, on peut l'adopter et gagner
// un ordre de grandeur. Sinon, le Pascal reste la seule option juste.
Log('');
Log('PBKDF2 natif (Android)...');
LSw := TStopwatch.StartNew;
LKey := DeriveKeyPBKDF2Native(TESTVECTOR_PASSWORD, LSalt, 600000, 32);
LSw.Stop;
if LKey = nil then
Log(' indisponible sur cette plateforme')
else
begin
LKeyHex := LowerCase(THash.DigestAsString(LKey));
Log(' duree : ' + IntToStr(LSw.ElapsedMilliseconds) + ' ms');
if LKeyHex = TESTVECTOR_KEY_HEX then
Log(' ==> IDENTIQUE — adoptable, encodage UTF-8 confirme')
else
begin
Log(' obtenu : ' + LKeyHex);
Log(' ==> DIFFERENT — encodage du char[] incompatible, garder le Pascal');
end;
end;
// ---- Etage 2 : AES-GCM + conteneur ------------------------------
Log('');
Log('Dechiffrement du conteneur...');