Created
October 26, 2017 11:40
-
-
Save Jim-Holmstroem/877e326c72cd6c349628712db1e7111f to your computer and use it in GitHub Desktop.
Generate a bcrypt password with salt only using `/dev/random` and with unambiguous characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
from __future__ import print_function, division | |
from itertools import ( | |
ifilter, | |
islice, | |
imap, | |
) | |
from functools import partial | |
import operator | |
import string | |
import sys | |
try: | |
import bcrypt | |
except ImportError as ie: | |
raise ImportError( | |
"bcrypt missing, install bcrypt by running:\n" | |
"sudo pip install bcrypt" | |
) | |
def take(sequence, n): | |
return list(islice(sequence, n)) | |
valid_characters = "".join(set(string.letters + string.digits) - set("lI10OQ")) | |
multiplier = (ord('\xff') + 1) // len(valid_characters) | |
assert(multiplier > 0) | |
n_characters = 12 | |
in_valid_character_range = lambda c: ord(c) < multiplier * len(valid_characters) | |
to_valid_character = lambda c: valid_characters[ord(c) // multiplier] | |
random_bytes = iter(lambda: open("/dev/random", "rb").read(1), None) | |
random_characters = imap( | |
to_valid_character, | |
ifilter( | |
in_valid_character_range, | |
random_bytes | |
) | |
) | |
def new_password(n_characters): | |
password = "".join( | |
take( | |
random_characters, | |
n_characters | |
) | |
).encode('utf-8') | |
return password | |
print("Wave your mouse to generate entropy, it can take a few seconds to get enough") | |
password = new_password(n_characters) | |
print("Password: {}".format(password)) | |
password_hash = bcrypt.hashpw(password, bcrypt.gensalt()) | |
print("Hash: {}".format(password_hash)) | |
print("Verify password and hash .. ", end='') | |
if bcrypt.checkpw(password, password_hash): | |
print("OK") | |
else: | |
print("Fail") | |
sys.exit(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment