werkzeug.generate_password_hash
хочет получить значение соли. Взглянув на источник, мы видим, что _hash_internal
вызывается с сгенерированным значением соли.
def generate_password_hash(password, method="pbkdf2:sha256", salt_length=8):
"""Hash a password with the given method and salt with a string of
the given length. The format of the string returned includes the method
that was used so that :func:`check_password_hash` can check the hash.
The format for the hashed string looks like this::
method$salt$hash
This method can **not** generate unsalted passwords but it is possible
to set param method='plain' in order to enforce plaintext passwords.
If a salt is used, hmac is used internally to salt the password.
If PBKDF2 is wanted it can be enabled by setting the method to
``pbkdf2:method:iterations`` where iterations is optional::
pbkdf2:sha256:80000$salt$hash
pbkdf2:sha256$salt$hash
:param password: the password to hash.
:param method: the hash method to use (one that hashlib supports). Can
optionally be in the format ``pbkdf2:<method>[:iterations]``
to enable PBKDF2.
:param salt_length: the length of the salt in letters.
"""
salt = gen_salt(salt_length) if method != "plain" else ""
h, actual_method = _hash_internal(method, salt, password)
return "%s$%s$%s" % (actual_method, salt, h)
Если мы вызываем _hash_internal
с помощью вашего sha1
метода и при условии соли / пароля, мы получаемдругой хеш
In [83]: import werkzeug.security
In [84]: h, method = werkzeug.security._hash_internal('sha1', 'e40e1e9addc186828a5554a71527342c', '123456')
In [86]: h == '784517f57fbe61179960739e29d7ae925aa4fd5b'
Out[86]: False
In [85]: h
Out[85]: 'e8c2de9bdc1ab92479e3e55b608a040dad7bf656'
Я думаю, что вам нужно пересмотреть ваш PHP-код, чтобы увидеть, как генерируются эти значения.
РЕДАКТИРОВАТЬ: согласно вашему комментарию
In [138]: werkzeug.security._hash_internal('sha1', '', 'e40e1e9addc186828a5554a71527342c123456')
Out[138]: ('784517f57fbe61179960739e29d7ae925aa4fd5b', 'sha1')
Если вы хотите использовать check_password_hash
, вам не нужно указывать соль в вашем хэше, а вместо этого добавлять его к своему паролю:
In [148]: werkzeug.check_password_hash('sha1$$784517f57fbe61179960739e29d7ae925aa4fd5b', 'e40e1e9addc186828a5554a71527342c123456')
Out[148]: True
Если мы посмотрим на источник, то увидим, что check_password_hash
извлекает method
, salt
и hashval
из pwhash
, затем проверяет хэшированные password
совпадения hashval
. Я не знаком с хэшированием в PHP, но кажется, что пароль был «засолен», а затем хеширован без соли (в любом случае, что касается werkzeug.security).
def check_password_hash(pwhash, password):
"""check a password against a given salted and hashed password value.
In order to support unsalted legacy passwords this method supports
plain text passwords, md5 and sha1 hashes (both salted and unsalted).
Returns `True` if the password matched, `False` otherwise.
:param pwhash: a hashed string like returned by
:func:`generate_password_hash`.
:param password: the plaintext password to compare against the hash.
"""
if pwhash.count("$") < 2:
return False
method, salt, hashval = pwhash.split("$", 2)
return safe_str_cmp(_hash_internal(method, salt, password)[0], hashval)