Quantcast
Channel: Recent Gists from 84adam
Viewing all articles
Browse latest Browse all 34

bcrypt/argon2/pbkdf2 hash test -- target a work factor that requires at least 250 ms to compute

$
0
0
bcrypt-argon2-pbkdf2-hash-test.py
# bcrypt-argon2-pbkdf2-hash-test.py
import threading
import bcrypt
from pwdlib.hashers import argon2
from pwdlib import PasswordHash
from pwdlib.hashers.argon2 import Argon2Hasher
from hashlib import pbkdf2_hmac
import time
import psutil
from statistics import median
def monitor_cpu():
while not stop_thread:
global cpu_load
cpu_load.append(psutil.cpu_percent(interval=1, percpu=True))
def hash_password(algorithm, work_factor, memory_cost=None):
password = b"your_secret_password"
start_time = time.time()
if algorithm == 'bcrypt':
_ = bcrypt.hashpw(password, bcrypt.gensalt(work_factor))
elif algorithm == 'pbkdf2':
# Assuming salt is also bytes; normally should be securely generated
salt = b'some_random_salt'
# pbkdf2_hmac requires the number of iterations, the salt, the desired hash name, and the password
_ = pbkdf2_hmac('sha256', password, salt, work_factor)
else:
# assume argon2
if memory_cost == None:
memory_cost = 65536 # 64 MiB; see: https://github.com/hynek/argon2-cffi/blob/0805dbdded04dc3c4bc8573236c80be50ff30113/src/argon2/profiles.py#L30-L38
password_hash = PasswordHash((
Argon2Hasher(time_cost=work_factor, memory_cost=memory_cost),
))
_ = password_hash.hash(password)
end_time = time.time()
if algorithm == 'argon2':
print(f"Hashing with {algorithm} work factor of {work_factor} and memory cost of {memory_cost} took {end_time - start_time:.3f} seconds.")
else:
print(f"Hashing with {algorithm} work factor of {work_factor} took {end_time - start_time:.3f} seconds.")
if __name__ == "__main__":
# select from: 'pbkdf2', 'argon2' or 'bcrypt'
algorithm = 'argon2'
# for argon2
memory_cost = 256 * 1024 # 256 MiB; see: https://github.com/sparrowwallet/drongo/blob/master/src/main/java/com/sparrowwallet/drongo/crypto/Argon2KeyDeriver.java
min_work = 5
max_work = 30
# for bcrypt
if algorithm == 'bcrypt':
if max_work > 20:
max_work = 20
# for argon2 / bcrypt
work_factors = [x for x in range(min_work, max_work+1)]
# for pbkdf2
if algorithm == 'pbkdf2':
min_work = 700_000
max_work = 1_000_000
work_factors = [x for x in range(min_work, max_work+1, 20_000)] # Increment by 20000 for noticeable differences
for work_factor in work_factors:
cpu_load = []
stop_thread = False
thread = threading.Thread(target=monitor_cpu)
thread.start()
try:
if algorithm in ['bcrypt', 'pbkdf2']:
hash_password(algorithm, work_factor)
elif algorithm == 'argon2':
hash_password(algorithm, work_factor, memory_cost)
else:
raise Exception(f"algorithm '{algorithm}' not configured")
finally:
stop_thread = True
thread.join()
all_max = []
all_avg = []
for index, cpu in enumerate(cpu_load):
all_max.append(max(cpu))
all_avg.append(sum(cpu) / len(cpu))
print(f"Max single CPU core usage: {max(all_max):.2f}%")
print(f"Average usage all cores during test: {(sum(all_avg) / len(all_avg)):.2f}%\n")

Viewing all articles
Browse latest Browse all 34

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>