Closed rubenmoral closed 4 months ago
I see there is a PR to fix this issue, #53. To minimize compatibility risks changing the H()
function, another alternative would be to replace the gen_x()
function with the following:
def gen_x( hash_class, salt, username, password ):
username = username.encode() if hasattr(username, 'encode') else username
password = password.encode() if hasattr(password, 'encode') else password
if _no_username_in_x:
username = six.b('')
h = hash_class()
h.update( username + six.b(':') + password )
usr_pwd_hash = h.digest()
h = hash_class()
h.update( salt )
h.update( usr_pwd_hash )
return int( h.hexdigest(), 16 )
Merged PR #53 to address this issue. Thanks for the report Ruben and thanks for reminding me that this PR was outstanding.
With certain combinations of username and password, the library does not calculate correctly
X
due to a wrong conversion between byte array and integer inH ( I | ":" | P )
, which loses the initial 0x00 byte(s), and the successive conversion from integer to byte array when hashing the salt along with the previous hash.Here's a detailed example of this issue happening when username is
apiservice
and password1257c
:H(apiservice:1257c) = 00d108f217cbcb3f960ddd7b776ba781ca8e079f21d454d27afaabaa6272f59c
The library converts this value to integer, which results in369332777322568772068616687266314200464576548617341020254200090987014059420
.d108f217cbcb3f960ddd7b776ba781ca8e079f21d454d27afaabaa6272f59c
. Note that this byte array is 1 byte less than the original because the first byte was00
. This causes the result hash value to be different than it should, which generates a totally differentX
.This only happens in the pure Python implementation, not in the ctypes one.