Vì vậy, hãy làm đúng.Mật khẩu PHP_verify() và Python bcrypt.hashpw()
Tôi đã thiết lập API REST REST đơn giản, nơi tôi nhận được mật khẩu băm thông qua khóa tiêu đề X-API-KEY. Điều này hoạt động tốt khi giao tiếp với một tập lệnh PHP khác và cụm từ được băm thông qua phương thức password_hash() của PHP. Tuy nhiên, khi tôi cố gắng giao tiếp với API thông qua Python và thư viện Yêu cầu, khóa bị từ chối. Dưới đây là một số mẫu:
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])
Sản lượng của mỗi trong số này là như sau:
PHP:
secret12345620161116
$2y$10$/WUBS2RkTlfcgPxvmqYRI.EkBD/CPgnpE9rYvOqweERgSwFeENUDO
5.6.24
Python:
secret12345620161116
$2b$11$9v/l6KglHiNgOybw1Y8jWeCFHiAfv.cguO1Qmc7Noe4azSluoBeHO
2.7.11
Bây giờ, rõ ràng họ là khác nhau , đó là điểm, nhưng khi bạn chuyển đầu ra Python tới hàm PHP password_verify(), nó trả về False. Sản lượng PHP xác minh tốt.
Có một điều gì đó tôi thiếu ở đây nhưng, đối với cuộc sống của tôi, tôi không thể tìm thấy nó. Tôi đã thử sử dụng các tùy chọn muối khác nhau mà không thành công. Tôi đang thiếu gì? Có phải hai không tương thích? Điều đó có vẻ ngớ ngẩn, nếu đó là sự thật.
Cảm ơn bạn, những người internet thông minh, nâng cao.
CẬP NHẬT
[Tôi đã cập nhật các kịch bản với 2 dòng sau cho các bài kiểm tra]
PHP: $hashed = password_hash($secret, PASSWORD_BCRYPT, ['cost'=>11]);
Python: hashed = bcrypt.hashpw(secret, bcrypt.gensalt(11))
Và tôi đã sử dụng này [PHP] để xác minh trên:
<?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";
?>
Với đầu ra sau:
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
Vì vậy, bây giờ tôi thực sự bối rối vì máy chủ vẫn không nhận ra khóa băm của tôi, nếu tôi không thay thế "$ 2b" bằng "$ 2y" như được gợi ý bởi richardhsu trong các nhận xét, Là.
Ngoài sự tò mò, bạn đã thử nghiệm phiên bản PHP và Python này bằng cách nào? –
Nếu bạn xuất 'bí mật' trong PHP và Python trước khi băm, chúng có giống nhau không? –
PHP đang sử dụng '$ 2y $' làm định danh thuật toán "bcrypt".Rõ ràng python sử dụng một định danh khác nhau. Ngoài ra, giá trị tiếp theo là chi phí. Chi phí khác nhau có nghĩa là một số chu kỳ khác nhau mà băm sẽ lặp lại. Hãy thử thay đổi các chi phí php để '11' như băm python (có thể được thiết lập như là một trong các tùy chọn để password_hash) và xem nếu nó dòng lên với băm python trừ đi các thuật toán. –