0

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

import string
from itertools import product
import crypt

def decrypt():
    hash1 = input("Please enter the hash: ")
    salt = input("Please enter the salt: ")
    charSet = string.ascii_letters + string.digits
    for wordchars in product(charSet, repeat=2):
        hash2 = crypt.METHOD_CRYPT((wordchars), (salt))
        print (hash2)

Obviously its not finished yet but I am having trouble encrypting "wordchars"

Any help is appreciated

jfs
  • 399,953
  • 195
  • 994
  • 1,670

4 Answers4

0

Hmm may be better use bcrypt? https://github.com/fwenzel/python-bcrypt

psaria
  • 59
  • 3
0

Below is a simple program that does what you asked:

def gen_word(charset, L):
    if L == 1: 
        for char in charset:
            yield char
        raise StopIteration
    for char in charset:
        for word in gen_word(charset, L - 1):
            yield char + word


def encrypt(word):
    '''Your encrypt function, replace with what you wish'''
    return word[::-1]


charset = ['1', '2', '3']


user_word = '12'
user_hash = encrypt(user_word)
max_length = 3


for length in range(1, max_length):
    for word in gen_word(charset, length):
        if encrypt(word) == user_hash:
            print 'Word found: %s' % word

Basically, it uses a python generator for generating words from the charset of fixed length. You can replace the encrypt function with whatever you want (in the example is string reversal used as hash).

Note that with actual modern hashing methods, it'll take forever to decrypt an ordinary password, so I don't think you could actually use this.

kaspersky
  • 3,959
  • 4
  • 33
  • 50
0

Here's my completely different answer based on J.F. Sebastian's answer and comment about my previous answer. The most important point being that crypt.METHOD_CRYPT is not a callable even though the documentation somewhat confusingly calls a hashing method as if it were a method function of a module or an instance. It's not -- just think of it as an id or name of one of the various kinds of encryption supported by the crypt module.

So the problem with you code is two-fold: One is that you were trying to use wordchars as a string, when it actually a tuple produced by product() and second, that you're trying to call the id crypt.METHOD_CRYPT.

I'm at a bit of a disadvantage answering this because I'm not running Unix, don't have Python v3.3 installed, and don't completely understand what you're trying to accomplish with your code. Given all those caveats, I think something like the following which is derived from you code ought to at least run:

import string
from itertools import product
import crypt

def decrypt():
    hash1 = input("Please enter the hash: ")
    salt = input("Please enter the salt: ")
    charSet = string.ascii_letters + string.digits
    for wordchars in product(charSet, repeat=2):
        hash2 = crypt.crypt(''.join(wordchars), salt=salt)  # or salt=crypt.METHOD_CRYPT
        print(hash2)
Community
  • 1
  • 1
martineau
  • 119,623
  • 25
  • 170
  • 301
  • METHOD_CRYPT is not callable. See [my answer](http://stackoverflow.com/a/13409383/4279) – jfs Nov 16 '12 at 02:18
0

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

Example

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.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • Brilliant, it works thank you very much. Just one other little thing is there a way i can set the "repeat" bit to search a range so it finds hash for character strings between 1-10 for example –  Nov 16 '12 at 12:56
  • @LWH91: note: for `repeat=10` it would take around a century if `repeat=4` executes in a second. Otherwise it is `itertools.chain.from_iterable(product(charset, repeat=r) for r in range(8))` for 0-7 case. – jfs Nov 16 '12 at 13:13
  • Hi again, your solution works fine for the hash you gave but when I try any hash I have it fails to crack it. My hashs are all in this format: aaacT.VSMxhms. Am I right in assuming the salt is "aa" and the hashed string is "acT.VSMxhms". I know that this hash is the word "moth". What hash format was the hash you used in your example and what does the assert line do? –  Nov 20 '12 at 21:42
  • @LWH91: run `crypt("moth", "aa")` and see what it returns. I've updated the answer to describe the assert. – jfs Nov 20 '12 at 22:06
  • what just run it in the terminal? thanks for clearing up the assert line –  Nov 20 '12 at 22:10
  • @LWH91: no. I meant call the function `crypt` with given parameters and inspect the returned value – jfs Nov 20 '12 at 22:15
  • I get a different hash as the return value, it returns 'aaXPqJ3632ccs'. Does this mean I cant use your answer? –  Nov 20 '12 at 22:20
  • I was running the code for about 8 hours trying to crack the month hash and it didnt manage to do it. How long should I expect it to take? –  Nov 21 '12 at 15:08
  • @LWH91: it takes 18 minutes on my machine. [Update your question](http://stackoverflow.com/posts/13401296/edit) or [post a new one](http://stackoverflow.com/questions/ask) with the minimal complete code example that reproduces your problem – jfs Nov 21 '12 at 20:29
  • @LWH91: http://sscce.org/ In your case check that it works for `'moth'` and doesn't produce any result for `'month'` in an hour. – jfs Nov 22 '12 at 13:18
  • im now running the code on a proper machine not a virtual one like i was doing before and it seems to be running better, just one more thing if the cursor stops flashing does that mean the program has crashed or is it still fine? –  Nov 22 '12 at 15:05