2022-03-23 22:00:35 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
import hashlib
|
|
|
|
import secrets
|
|
|
|
|
|
|
|
|
|
|
|
def rfc2440_hash_password(password, salt=None):
|
|
|
|
# Match tor --hash-password
|
|
|
|
# secret_to_key_rfc2440
|
|
|
|
|
|
|
|
EXPBIAS = 6
|
|
|
|
c = 96
|
|
|
|
count = (16 + (c & 15)) << ((c >> 4) + EXPBIAS)
|
|
|
|
|
|
|
|
if salt is None:
|
|
|
|
salt = secrets.token_bytes(8)
|
2022-07-31 18:01:49 +00:00
|
|
|
assert len(salt) == 8
|
2022-03-23 22:00:35 +00:00
|
|
|
|
|
|
|
hashbytes = salt + password.encode('utf-8')
|
|
|
|
len_hashbytes = len(hashbytes)
|
|
|
|
h = hashlib.sha1()
|
|
|
|
|
|
|
|
while count > 0:
|
|
|
|
if count >= len_hashbytes:
|
|
|
|
h.update(hashbytes)
|
|
|
|
count -= len_hashbytes
|
|
|
|
continue
|
|
|
|
h.update(hashbytes[:count])
|
|
|
|
break
|
|
|
|
rv = '16:' + salt.hex() + '60' + h.hexdigest()
|
|
|
|
return rv.upper()
|