I am trying to encrypt all possible strings in a defined character set then compare them to a hash given by user input.
This is what I currently have
imp
crypt.METHOD_CRYPT
is not callable so the traceback that you provided doesn't correspond to the code in your question. crypt.METHOD_CRYPT
could be used as the second parameter for crypt.crypt() function.
Also as @martineau pointed out wordchars
is a tuple but you need a string to pass to the crypt.crypt()
function.
From the docs:
Since a few crypt(3) extensions allow different values, with different sizes in the salt, it is recommended to use the full crypted password as salt when checking for a password.
To find a plain text from a defined character set given its crypted form: salt plus hash, you could:
from crypt import crypt
from itertools import product
from string import ascii_letters, digits
def decrypt(crypted, charset=ascii_letters + digits):
# find hash for all 4-char strings from the charset
# and compare with the given hash
for candidate in map(''.join, product(charset, repeat=4)):
if crypted == crypt(candidate, crypted):
return candidate
salt, hashed = 'qb', '1Y.qWr.DHs6'
print(decrypt(salt + hashed))
# -> e2e4
assert crypt('e2e4', 'qb') == (salt + hashed)
The assert line makes sure that calling crypt
with the word e2e4
and the salt qb
produces qb1Y.qWr.DHs6
where qb
is the salt.