Portál AbcLinuxu, 26. října 2025 07:52
vstupní: _U9..vnIfeJymPPkVwPU výstupní: _UbD.ypiMD0vwV čem je problém?
Řešení dotazu:
<?php
$password = crypt('mypassword'); // let the salt be automatically generated
/* You should pass the entire results of crypt() as the salt for comparing a
password, to avoid problems when different hashing algorithms are used. (As
it says above, standard DES-based password hashing uses a 2-character salt,
but MD5-based hashing uses 12.) */
if (crypt($user_input, $password) == $password) {
echo "Password verified!";
}
?>
Pokud funkcí crypt vygeneruju jakýkoliv hash kromě extended-des tak se to dá takto ověřit. Pro extended-des to nefunguje:
$password = crypt('retezec', '_U9..dCaX');
(crypt('retezec', $password) == $password) : toto je vždy FALSE
debian/patches/php_crypt_revamped.patch a copak nevidím v ext/standard/crypt.c:
if (salt[0]=='$' && salt[1]=='1' && salt[2]=='$') {
/* CRYPT_MD5 */
#if PHP_MD5_CRYPT
# warning Using system MD5 crypt function, which is OK on Debian system
# if PHP_USE_SYSTEM_CRYPT_R
crypt_res = crypt_r(str, salt, &buffer);
# else
crypt_res = crypt(str, salt);
# endif
#elif PHP_USE_PHP_CRYPT_R
# error Using PHP MD5 crypt function, should not happen on Debian system
crypt_res = php_md5_crypt_r(str, salt, output);
#endif
} else if (salt[0]=='$' && salt[1]=='6' && salt[2]=='$') {
/* CRYPT_SHA512 */
#if PHP_SHA512_CRYPT
# warning Using system SHA512 crypt function, which is OK on Debian system
# if PHP_USE_SYSTEM_CRYPT_R
crypt_res = crypt_r(str, salt, &buffer);
# else
crypt_res = crypt(str, salt);
# endif
#elif PHP_USE_PHP_CRYPT_R
# error Using PHP SHA512 crypt function, should not happen on Debian system
crypt_res = php_sha512_crypt_r(str, salt, output, sizeof(output));
#endif
} else if (salt[0]=='$' && salt[1]=='5' && salt[2]=='$') {
/* CRYPT_SHA256 */
#if PHP_SHA256_CRYPT
# warning Using system SHA256 crypt function, which is OK on Debian system
# if PHP_USE_SYSTEM_CRYPT_R
crypt_res = crypt_r(str, salt, &buffer);
# else
crypt_res = crypt(str, salt);
# endif
#elif PHP_USE_PHP_CRYPT_R
# error Using PHP SHA256 crypt function, should not happen on Debian system
crypt_res = php_sha256_crypt_r(str, salt, output, sizeof(output));
#endif
} else if (
salt[0] == '$' &&
salt[1] == '2' &&
salt[2] == 'a' &&
salt[3] == '$' &&
salt[6] == '$' &&
((salt[4] == '0' &&
salt[5] >= '4' && salt[5] <= '9') ||
(salt[4] >= '1' && salt[4] <= '2' &&
salt[5] >= '0' && salt[5] <= '9') ||
(salt[4] == '3' &&
salt[5] >= '0' && salt[5] <= '1'))) {
/* CRYPT_BLOWFISH */
#if PHP_BLOWFISH_CRYPT
# error Using system BlowFish crypt function, should not happen on Debian system
# if PHP_USE_SYSTEM_CRYPT_R
crypt_res = crypt_r(str, salt, &buffer);
# else
crypt_res = crypt(str, salt);
# endif
#elif PHP_USE_PHP_CRYPT_R
# warning Using PHP BlowFish crypt function, which is OK on Debian system
crypt_res = php_crypt_blowfish_rn(str, salt, output, sizeof(output));
#endif
} else if (salt[0]=='_' &&
salt_len == 9) {
/* CRYPT_EXT_DES */
#if PHP_EXT_DES_CRYPT
# error Using system extended DES crypt function, should not happen on Debian system
# if PHP_USE_SYSTEM_CRYPT_R
crypt_res = crypt_r(str, salt, &buffer);
# else
crypt_res = crypt(str, salt);
# endif
#elif PHP_USE_PHP_CRYPT_R
# warning Using PHP extended DES crypt function, which is OK on Debian system
_crypt_extended_init_r();
crypt_res = _crypt_extended_r(str, salt, &extended_buffer);
#endif
} else {
/* CRYPT_STD_DES */
#if PHP_STD_DES_CRYPT
# warning Using system standard DES crypt function, which is OK on Debian system
# if PHP_USE_SYSTEM_CRYPT_R
crypt_res = crypt_r(str, salt, &buffer);
# else
crypt_res = crypt(str, salt);
# endif
#elif PHP_USE_PHP_CRYPT_R
# error Using PHP standard DES crypt function, should not happen on Debian system
_crypt_extended_init_r();
crypt_res = _crypt_extended_r(str, salt, &extended_buffer);
#endif
}
Jak je na první pohled jasné, zatímco u standardního DES a u saltů s dolary to funguje, i když je samotný hash součástí saltu, tak zrovna u extended DES se testuje, zda je délka hashe přesně 9. Pokud je 9, zavolá se funkce _crypt_extended_r, která extended DES umí. No a pokud není délka 9, použije se postup pro standardní DES - což je právě volání systémového crypt, který extended DES neumí. (To, že se to volá přesně takto, jsem si ověřil debuggerem.)
V upstream zdrojovych kodech PHP je tato část jinak - tam by ext des nejspíš buď fungovalo, nebo nefungovalo vůbec :).
Jako oprava by stačilo odstranění salt_len == 9 - v saltu standardního DESu by podtržítko být nemělo, takže standardní DES se od extended pozná i tak.
Není mi moc jasné, kde přesně se ty patche berou, tak nevím, komu můžeš poděkovat - zda maintainerům Debianu, nebo PHP.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.