hash_pbkdf2() wastes time by repeatedly hashing the HMAC key blocks
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- C
- Estrellas
- 40.4k
- Forks
- 8.2k
- Merge medio
- 2 d 13 h
- PR fusionados (30 d)
- 96
Descripción
Description
As mentioned in a 2015 blog post titled "PBKDF2: performance matters", hash_pbkdf2() is missing an important optimization that relates specifically to the use of HMAC for the underlying pseudorandom function. This means it "[...] is at least two times slower than it otherwise could be."
The author of the blog post linked to a pull request he had made against PHP 5.6 (#1387), which unfortunately did not get a review before it was closed as stale in 2017. I have attempted to update his patch for PHP 8.0 (the lowest supported version at the time I am writing this report), and I am creating a new pull request for it. I hope that this time the PHP developers will take a look.
Below is a test script that demonstrates that the optimization is missing.
The following code:
<?php
function test_native() {
$st = hrtime(true);
$h = hash_pbkdf2('sha256', 'password', 'salt', 100000);
$et = hrtime(true);
return [$h, $et - $st];
}
function test_emulated() {
$st = hrtime(true);
$K = str_pad('password', 64, "\0");
$K ^= str_repeat("\x36", 64);
$ictx = hash_init('sha256');
hash_update($ictx, $K);
$K ^= str_repeat("\x6a", 64);
$octx = hash_init('sha256');
hash_update($octx, $K);
$DK = str_repeat("\0", 32);
$prev = "salt\0\0\0\1";
for ($j = 0; $j < 100000; ++$j) {
$ctx = hash_copy($ictx);
hash_update($ctx, $prev);
$temp = hash_final($ctx, true);
$ctx = hash_copy($octx);
hash_update($ctx, $temp);
$prev = hash_final($ctx, true);
$DK ^= $prev;
}
$h = bin2hex($DK);
$et = hrtime(true);
return [$h, $et - $st];
}
$nr = test_native();
$er = test_emulated();
var_dump($nr[0]);
var_dump($er[0]);
var_dump($nr[1] <= $er[1]);
Resulted in this output:
string(64) "0394a2ede332c9a13eb82e9b24631604c31df978b4e2f0fbd2c549944f9d79a5"
string(64) "0394a2ede332c9a13eb82e9b24631604c31df978b4e2f0fbd2c549944f9d79a5"
bool(false)
But I expected this output instead:
string(64) "0394a2ede332c9a13eb82e9b24631604c31df978b4e2f0fbd2c549944f9d79a5"
string(64) "0394a2ede332c9a13eb82e9b24631604c31df978b4e2f0fbd2c549944f9d79a5"
bool(true)
PHP Version
PHP 8.1.10
Operating System
No response
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza en el punto de entrada hash_pbkdf2() y reproduce el benchmark de PHP proporcionado, comparando PBKDF2 nativo con la versión emulada. El trabajo está terminado cuando la optimización conserva el digest mostrado y el tiempo de ejecución nativo cumple con la comparación esperada.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- c, php
- Área
- cryptography, performance
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 45/100