Tak, właśnie do niego.PHP password_verify() vs Python bcrypt.hashpw()
Mam ustawione [proste] PHP REST API, gdzie otrzymuję hashowane hasło za pomocą klucza nagłówkowego X-API-KEY. Działa to świetnie, gdy współpracujesz z innym skryptem PHP, a fraza jest mieszana za pomocą metody password_hash(). Jednak gdy próbuję połączyć się z interfejsem API za pośrednictwem Pythona i biblioteki Requests, klucz jest odrzucany. Oto kilka próbek:
PHP:
<?php
$usrid = '123456';
$dt = new DateTime();
$secret = "secret{$usrid}{$dt->format('Ymd')}";
$hashed = password_hash($secret, PASSWORD_BCRYPT);
echo $secret."\n";
echo $hashed."\n";
echo(phpversion());
?>
Python:
#!/usr/bin/python
import bcrypt, datetime, sys
usrid = '123456' # user id
t = datetime.datetime.now().strftime('%Y%m%d')
secret = "secret{usrid}{t}".format(usrid=usrid,t=t)
hashed = bcrypt.hashpw(secret, bcrypt.gensalt())
print secret
print hashed
print '%d.%d.%d' % (sys.version_info[:3])
Wyjście każdy z nich jest w następujący sposób:
PHP:
secret12345620161116
$2y$10$/WUBS2RkTlfcgPxvmqYRI.EkBD/CPgnpE9rYvOqweERgSwFeENUDO
5.6.24
Python:
secret12345620161116
$2b$11$9v/l6KglHiNgOybw1Y8jWeCFHiAfv.cguO1Qmc7Noe4azSluoBeHO
2.7.11
Teraz, oczywiście są one różne , to jest sedno, ale kiedy przekazujesz wyjście Pythona do funkcji PHP password_verify(), to zwraca False. Wynik PHP weryfikuje się dobrze.
Musi tu być coś, czego tu brakuje, ale nie mogę go znaleźć na całe życie. Próbowałem używać różnych opcji soli bez powodzenia. czego mi brakuje? Czy te dwa po prostu nie są kompatybilne? To wydaje się głupie, jeśli to prawda.
Dziękuję zaawansowanym, inteligentnym ludziom internetowym.
UPDATE
[I zostały zaktualizowane skrypty z następujących 2 linie do testów]
PHP: $hashed = password_hash($secret, PASSWORD_BCRYPT, ['cost'=>11]);
Python: hashed = bcrypt.hashpw(secret, bcrypt.gensalt(11))
I Użyłem tego [php], aby zweryfikować powyższą:
<?php
$secret = 'secret12345620161116';
$php = '$2y$11$rMqK7PhWtYd3E6yqqor0K.p2XEOJqbxJSrknLLWfhqZKsbYRa1YRa'; // output from php script
$python = '$2b$11$yWzCNB4dfIIVH2FLWWEQ/efSmN/KlVmLq.MGJ54plgedE1OSQgvPu'; // putput from python script
$php_needs_rehash = password_needs_rehash($php, PASSWORD_BCRYPT);
$python_needs_rehash = password_needs_rehash($python, PASSWORD_BCRYPT);
echo 'php_needs_rehash: '.$php_needs_rehash."\n";
echo 'python_needs_rehash: '.$python_needs_rehash."\n";
echo "\n";
echo "php_info:\n";
print_r(password_get_info($php));
echo "\n";
echo "python_info:\n";
print_r(password_get_info($python));
echo "\n";
echo "php_verified: ".password_verify($secret, $php)."\n";
echo "python_verified: ".password_verify($secret, $python)."\n";
echo "\n";
?>
Z następującą wydajnością:
php_needs_rehash: 1
python_needs_rehash: 1
php_info:
Array
(
[algo] => 1
[algoName] => bcrypt
[options] => Array
(
[cost] => 11
)
)
python_info:
Array
(
[algo] => 0
[algoName] => unknown
[options] => Array
(
)
)
php_verified: 1
python_verified: 1
Tak więc, teraz jestem bardzo zdezorientowany, ponieważ serwer nadal nie rozpoznaje mojego zakodowanego klucza pytona, jeśli nie zastąpię "2 dolców" za pomocą "2 dolców", jak zasugerował richardhsu w komentarzach, że jest.
Z ciekawości, jakie wersje PHP i Python testowałeś? –
Jeśli wypiszesz 'secret' w PHP i Pythonie przed haszowaniem, czy są one takie same? –
PHP używa '$ 2y $' jako identyfikatora algorytmu "bcrypt".Podobno Python używa innego identyfikatora. Kolejną wartością jest koszt. Różne koszty oznaczają inną liczbę cykli, którą powtarza hasz. Spróbuj zmienić koszt php na '11', tak jak hash pytona (można ustawić jako jedną z opcji password_hash) i sprawdzić, czy pasuje do skrótu Pythona minus algorytm. –