tedbates
Posts: 4
Joined: Thu Apr 07, 2016 4:23 pm
Occupation: Parent

crack2.py Python question...

Postby tedbates » Thu Apr 07, 2016 4:29 pm

Hello,

I have been helping my son with the crack2.py password guessing program and we have been doing well with it. The problem we are having is, the program will not guess ANY punctuation.

I can type in a single exclamation mark and the program will not guess it. I'm running the program on a windows 10 laptop with an i7 processor and Python 3+ (don't remember exactly what version, it's greater than 3).

I changed the "wheel" to include punctuation and that didn't help. Right now as I'm typing the program is searching for a single exclamation mark, and the CPU fan just kicked into high gear....

If anybody can throw me some suggestions I would greatly appreciate it. Thanks in advance for your help!

tedbates
Posts: 4
Joined: Thu Apr 07, 2016 4:23 pm
Occupation: Parent

Re: crack2.py Python question...

Postby tedbates » Fri Apr 08, 2016 2:07 pm

The program won't find capitalized letters either. I can type in "Cow" and an hour later it's still searching....

HowardE
Posts: 496
Joined: Thu Nov 20, 2014 1:35 pm
Occupation: Science Buddies content developer

Re: crack2.py Python question...

Postby HowardE » Fri Apr 08, 2016 4:06 pm

tedbates-

I'm sorry you had trouble with that program, but you were on the right track by adding the punctuation to the wheel in method 2. The piece of the puzzle you might have missed is that the algorithm needs to know how many positions the wheel has. In the version you downloaded it was set to 62 in the code below:

Code: Select all

            if pass_wheel_array[i] > 62:
                pass_wheel_array[i] = 1
                carry = 1
                if i == (num_pass_wheels-1):
                    still_searching = False


If you had added in just the "!" and then changed that to 63, it would have worked. Also, I don't see any reason why it wouldn't have found "Cow" using method 2 since it's composed of upper and lower case characters and 8 chars or fewer.

I've attached a modified version that added punctuation to the wheel (making it bigger than the original 62) which also measures the length of the string and uses that instead of using a hardcoded figure. It will run slower but a program that works at all is better than one that won't guess your password, right?

This code sets u the new expanded wheel:

Code: Select all

    punctuation="~!@#$%^&*()_-+={}[]:<>,./"
    chars = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
    wheel = chars + punctuation
    wheelsize = len(wheel)
    print("The wheel is "+str(wheelsize)+" characters, including "+str(len(punctuation))+ " punctuation characters.")


The new test looks like this instead:

Code: Select all

            if pass_wheel_array[i] > wheelsize-1:
                pass_wheel_array[i] = 1
                carry = 1
                if i == (num_pass_wheels-1):
                    still_searching = False


Here it's finding "Cow" and "!"-
    Science Buddies: How Easily Can Your password Be Hacked?
    Which password (0-6)? 0
    Trying to guess password 0
    Using method 3 with 435 in the list
    The search took 0.0 seconds for 870 tests or 1,067,596 tests per second.
    Using method 4 with 26 punc chars and 435 in the list
    The search took 26 seconds for 19,679,400 tests or 768,525 tests per second.
    Using method 1 and searching for 1 digit numbers.
    The search took 0.04 seconds for 10 tests or 203 tests per second.
    Using method 1 and searching for 2 digit numbers.
    The search took 0.05 seconds for 100 tests or 1,905 tests per second.
    Using method 1 and searching for 3 digit numbers.
    The search took 0.05 seconds for 1,000 tests or 19,903 tests per second.
    Using method 1 and searching for 4 digit numbers.
    The search took 0.07 seconds for 10,000 tests or 141,096 tests per second.
    Using method 2 and searching with 6 password wheels.
    The wheel is 88 characters, including 25 punctuation characters.
    Success! Password 0 is Cow
    The search took 0.28 seconds for 26,323 tests or 90,795 tests per second.
    The total search for all methods took 27 seconds and 19,717,703 guesses.(741,677 guesses per second)
    Your algorithm correctly guessed the password you entered. Try some others or see if you can make it guess faster.
    >>>
    Science Buddies: How Easily Can Your password Be Hacked?
    Which password (0-6)? 0
    Trying to guess password 0
    Using method 3 with 435 in the list
    The search took 0.0 seconds for 870 tests or 1,211,502 tests per second.
    Using method 4 with 26 punc chars and 435 in the list
    The search took 25 seconds for 19,679,400 tests or 784,960 tests per second.
    Using method 1 and searching for 1 digit numbers.
    The search took 0.04 seconds for 10 tests or 200 tests per second.
    Using method 1 and searching for 2 digit numbers.
    The search took 0.05 seconds for 100 tests or 1,982 tests per second.
    Using method 1 and searching for 3 digit numbers.
    The search took 0.05 seconds for 1,000 tests or 19,425 tests per second.
    Using method 1 and searching for 4 digit numbers.
    The search took 0.06 seconds for 10,000 tests or 153,958 tests per second.
    Using method 2 and searching with 6 password wheels.
    The wheel is 88 characters, including 25 punctuation characters.
    Success! Password 0 is !
    The search took 0.15 seconds for 64 tests or 426 tests per second.
    The total search for all methods took 26 seconds and 19,691,444 guesses.(759,869 guesses per second)
    Your algorithm correctly guessed the password you entered. Try some others or see if you can make it guess faster.


Here is the complete version. Try this instead of the version on the site and see if it makes more sense to you.

Code: Select all

#!/usr/bin/python

# This program is offered for use with the Science Buddies project idea
# "How Easily Can Your Password Be Hacked?" which lets you explore the
# makeup of a good password. This program will help you understand some
# methods that people use to guess other people's passwords.
#
# the program begins execution at 'main' after the helper programs and functions
# are defined. You'll also notice that several functions have places where
# print() functions have been turned into comments. When debugging a program, it's
# helpful to add in more descriptive screen output than you might want later on.
# Once the program is working, you can remove the extra output os, as we've done here,
# 'comment it out' so that someone else can use it again later on if they decide to
# modify your program.

#Tell Python we want to use some functions it doesn't always use
import sys, time, hashlib
from array import *

#--------------- global variables we expect will be used by any function -----------
#
# a number from 1 to 6 selects which password we'll be trying to guess from
# a selection below.
which_password = 0

# the user names and password we're trying to 'crack'. These will get written
password0 = ""
password1 = ""
password2 = ""
password3 = ""
password4 = ""
password5 = ""
password6 = ""


# total number of guesses we had to make to find it
totalguesses = 0


#--------------- extra helper functions -------------------
# These will be used by our search routines later on. We'll get these defined and out
# of the way. The actual search program is called "main" and will be the last one
# defined. Once it's defined, the last statement in the file runs it.
#
#


## Convert a string into MD5 hash
def MD5me(s):
    result = s.encode("utf-8")
    result = hashlib.md5(result).hexdigest()
    return result

# Takes a number from 0 on up and the number of digits we want it to have. It uses that
# number of digits to make a string like "0000" if we wanted 4 or "00000" if we wanted
# 5, converts our input number to a character string, sticks them together and then returns
# the number we started with, with extra zeroes stuck on the beginning.
def leading_zeroes(n, zeroes):
    t=("0"*zeroes)+str(n)
    t=t[-zeroes:]
    return t

# check_userpass
def check_userpass(which_password, password):
    global password0, password1, password2, password3
    global password4, password5, password6
   
    result = False

    if (0 == which_password):
        if password == password0:
            result = True

    if (1 == which_password):
        if MD5me(password) == password1:
            result = True

    if (2 == which_password):
        if (MD5me(password) == password2):
            result = True

    if (3 == which_password):
        if (MD5me(password) == password3):
            result = True

    if (4 == which_password):
        if (MD5me(password) == password4):
            result = True
           
    if (5 == which_password):
        if (MD5me(password) == password5):
            result = True
           
    if (6 == which_password):
        if (MD5me(password) == password6):
            result = True
           
    return result

# This displays the results of a search including tests per second when possible
def report_search_time(tests, seconds):
    if (seconds > 0.000001):
        print ("The search took "+make_human_readable(seconds)+" seconds for "+make_human_readable(tests)+" tests or "+make_human_readable(tests/seconds)+" tests per second.")
    else:
        print ("The search took "+make_human_readable(seconds)+" seconds for "+make_human_readable(tests)+" tests.")
    return

# search method 1 will try using digits as the password.
def search_method_1(num_digits):
    global totalguesses
    result = False
    a=0
    #num_digits = 3    # How many digits to try. 1 = 0 to 9, 2 = 00 to 99, etc.
    starttime = time.time()
    tests = 0
    still_searching = True
    print("Using method 1 and searching for "+str(num_digits)+" digit numbers.")
    while still_searching and a<(10**num_digits):
        ourguess = leading_zeroes(a,num_digits)
        tests = tests + 1
        totalguesses = totalguesses + 1
        if (check_userpass(which_password, ourguess)):
            print ("Success! Password "+str(which_password)+" is " + ourguess)
            still_searching = False   # we can stop now - we found it!
            result = True
        #else:
            #print ("Darn. " + ourguess + " is NOT the password.")
        a=a+1

    seconds = time.time()-starttime
    report_search_time(tests, seconds)
    return result

# search method 2 is a simulation of a letter-style combination lock. Each'wheel' has the
# letters A-Z, a-z and 0-9 on it as well as a blank. The idea is that we have a number of
# wheels for a user name and password and we try each possible combination.
#
# April 8, 2016 - This is a tweaked version which adds some punctuation to the original 62 element
#                 'wheel' and then uses strlen() to measure the size of the wheel rather than use a hardoded
#                 number. Hardcoding it does make it run faster, but it's also confusing to some people. So while
#                 this tweaked version is more flexible it's also going to run more slowly.
def search_method_2(num_pass_wheels):
    global totalguesses
    result = False
    starttime = time.time()
    tests = 0
    still_searching = True
    print("Using method 2 and searching with "+str(num_pass_wheels)+" password wheels.")
    punctuation="~!@#$%^&*()_-+={}[]:<>,./"
    chars = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
    wheel = chars + punctuation
    wheelsize = len(wheel)
    print("The wheel is "+str(wheelsize)+" characters, including "+str(len(punctuation))+ " punctuation characters.")
    # we only allow up to 8 wheels for each password for now
    if (num_pass_wheels > 8):
        print("Unable to handle the request. No more than 8 characters for a password")
        still_searching = False
    # set all of the wheels to the first position
    pass_wheel_array=array('i',[1,0,0,0,0,0,0,0,0])
       
    while still_searching:
        ourguess_pass = ""
        for i in range(0,num_pass_wheels):  # once for each wheel
            if pass_wheel_array[i] > 0:
                ourguess_pass = wheel[pass_wheel_array[i]] + ourguess_pass
        #print ("trying ["+ourguess_pass+"]")
        if (check_userpass(which_password, ourguess_pass)):
            print ("Success! Password  "+str(which_password)+" is " + ourguess_pass)
            still_searching = False   # we can stop now - we found it!
            result = True
        #else:
            #print ("Darn. " + ourguess + " is NOT the password.")
        tests = tests + 1
        totalguesses = totalguesses + 1
# spin the rightmost wheel and if it changes, spin the next one over and so on
        carry = 1
        for i in range(0,num_pass_wheels): # once for each wheel
            pass_wheel_array[i] = pass_wheel_array[i] + carry
            carry = 0
            if pass_wheel_array[i] > wheelsize-1:
                pass_wheel_array[i] = 1
                carry = 1
                if i == (num_pass_wheels-1):
                    still_searching = False

    seconds = time.time()-starttime
    report_search_time(tests, seconds)
    return result

# This function takes in numbers, rounds them to the nearest integer and puts
# commas in to make it more easily read by humans
def make_human_readable(n):
    if n>=1:
        result = ""
        temp=str(int(n+0.5))
        while temp != "":
            result = temp[-3:] + result
            temp = temp[:-3]
            if temp != "":
                result = "," + result
    else:
        temp = int(n*100)
        temp = temp /100
        result = str(temp)
    return result
       
## A little helper program to remove any weird formatting in the file
def cleanup (s):
    s = s.strip()
    return s

## A little helper program that capitalizes the first letter of a word
def Cap (s):
    s = s.upper()[0]+s[1:]
    return s


# search method 3 uses a list of dictionary words. In this case, we have a list
# of the 500 most commonly used passwords in 2005 as collected by Mark Burnett
# for his book "Perfect Passwords" (ISBN 978-1597490412). Because the list comes
# from so many people around the world, we had to remove some of the passwords.
# People like to use passwords that they think will shock other people, so
# sometimes they're not fit for polite company.
def search_method_3(file_name):
    global totalguesses
    result = False
   
    # Start by reading the list of words into a Python list
    f = open(file_name)
    words = f.readlines()
    f.close
    # We need to know how many there are
    number_of_words = len(words)
    print("Using method 3 with "+str(number_of_words)+" in the list")
   
    ## Depending on the file system, there may be extra characters before
    ## or after the words.
    for i in range(0, number_of_words):
        words[i] = cleanup(words[i])

    # Let's try each one as the password and see what happens
    starttime = time.time()
    tests = 0
    still_searching = True
    word1count = 0           # Which word we'll try next

    while still_searching:
        ourguess_pass = words[word1count]
        #print("Guessing: "+ourguess_pass)
        # Try it the way it is in the word list
        if (check_userpass(which_password, ourguess_pass)):
            print ("Success! Password "+str(which_password)+" is " + ourguess_pass)
            still_searching = False   # we can stop now - we found it!
            result = True
        #else:
            #print ("Darn. " + ourguess_pass + " is NOT the password.")
        tests = tests + 1
        totalguesses = totalguesses + 1
        # Now let's try it with the first letter capitalized
        if still_searching:
            ourguess_pass = Cap(ourguess_pass)
            #print("Guessing: "+ourguess_pass)
            if (check_userpass(which_password, ourguess_pass)):
                print ("Success! Password "+str(which_password)+" is " + ourguess_pass)
                still_searching = False   # we can stop now - we found it!
                result = True
            #else:
                #print ("Darn. " + ourguess_pass + " is NOT the password.")
            tests = tests + 1
            totalguesses = totalguesses + 1

        word1count = word1count + 1
        if (word1count >=  number_of_words):
            still_searching = False

    seconds = time.time()-starttime
    report_search_time(tests, seconds)
    return result
           
## Search method 4 is similar to 3 in that it uses the dictionary, but it tries two
## two words separated by a punctuation character
def search_method_4(file_name):
    global totalguesses
    result = False
   
    # Start by reading the list of words into a Python list
    f = open(file_name)
    words = f.readlines()
    f.close
    # We need to know how many there are
    number_of_words = len(words)
   
    ## Depending on the file system, there may be extra characters before
    ## or after the words.
    for i in range(0, number_of_words):
        words[i] = cleanup(words[i])

    # Let's try each one as the password and see what happens
    starttime = time.time()
    tests = 0
    still_searching = True
    word1count = 0           # Which word we'll try next
    punc_count = 0
    word2count = 0

    punctuation="~!@#$%^&*()_-+={}[]:<>,./X"  # X is a special case where we omit
                                              # the punctuation to run the words together

    number_of_puncs = len(punctuation)
    print("Using method 4 with "+str(number_of_puncs)+" punc chars and "+str(number_of_words)+" in the list")

    while still_searching:
        if ("X" == punctuation[punc_count]):
            # If we're at the end of the string and found the 'X', leave it out
            ourguess_pass = words[word1count] + words[word2count]
        else:
            ourguess_pass = words[word1count] + punctuation[punc_count] + words[word2count]
        #print("Guessing: "+ourguess_pass)
        # Try it the way they are in the word list
        if (check_userpass(which_password, ourguess_pass)):
            print ("Success! Password "+str(which_password)+" is " + ourguess_pass)
            still_searching = False   # we can stop now - we found it!
            result = True
        #else:
            #print ("Darn. " + ourguess_pass + " is NOT the password.")
        tests = tests + 1
        totalguesses = totalguesses + 1
        # Now let's try it with the first letter of the first word capitalized
        if still_searching:
            ourguess_pass = Cap(words[word1count]) + punctuation[punc_count] + words[word2count]
            #print("Guessing: "+ourguess_pass)
            if (check_userpass(which_password, ourguess_pass)):
                print ("Success! Passwword "+str(which_password)+" is " + ourguess_pass)
                still_searching = False   # we can stop now - we found it!
                result = True
            #else:
                #print ("Darn. " + ourguess_pass + " is NOT the password.")
            tests = tests + 1
            totalguesses = totalguesses + 1
        # Now let's try it with the first letter of the second word capitalized
        if still_searching:
            ourguess_pass = words[word1count] + punctuation[punc_count] + Cap(words[word2count])
            #print("Guessing: "+ourguess_pass)
            if (check_userpass(which_password, ourguess_pass)):
                print ("Success! Password "+str(which_password)+" is " + ourguess_pass)
                still_searching = False   # we can stop now - we found it!
                result = True
            #else:
                #print ("Darn. " + ourguess_pass + " is NOT the password.")
            tests = tests + 1
            totalguesses = totalguesses + 1
        # Now let's try it with the both words capitalized
        if still_searching:
            ourguess_pass = Cap(words[word1count]) + punctuation[punc_count] + Cap(words[word2count])
            #print("Guessing: "+ourguess_pass)
            if (check_userpass(which_password, ourguess_pass)):
                print ("Success! Password "+str(which_password)+" is " + ourguess_pass)
                still_searching = False   # we can stop now - we found it!
                result = True
            #else:
                #print ("Darn. " + ourguess_pass + " is NOT the password.")
            tests = tests + 1
            totalguesses = totalguesses + 1

        word1count = word1count + 1
        if (word1count >=  number_of_words):
            word1count = 0
            punc_count = punc_count + 1
            if (punc_count >= number_of_puncs):
                punc_count = 0
                word2count = word2count + 1
                if (word2count >= number_of_words):
                    still_searching = False

    seconds = time.time()-starttime
    report_search_time(tests, seconds)
    return result


def main(argv=None):
    global password0, password1, password2, password3
    global password4, password5, password6, totalguesses
    global which_password

    # This is a place for you to set a password of your own
    password0 = "314"
    # Set up the passwords we want to crack. These must be MD5 hash
    # data blocks. Set them up using MD5me like:
    #     'password1=MD5me("ScienceBuddies")'
    #
    password1="202cb962ac59075b964b07152d234b70"
    password2="570a90bfbf8c7eab5dc5d4e26832d5b1"
    password3="f78f2477e949bee2d12a2c540fb6084f"
    password4="09408af74a7178e95b8ddd4e92ea4b0e"
    password5="2034f6e32958647fdff75d265b455ebf"
    password6="9b3af42d61cde121f40b96097fb77d3e"

    # start searching
    which_password = 1
    which_password = int(input("Which password (0-6)? "))
    overallstart = time.time()
    foundit = False
    print("Trying to guess password "+str(which_password))
    # Look through our list of common passwords first
    if not foundit:
        foundit = search_method_3("passwords.txt")
    # Still looking? Let's combine the common passwords 2 at a time
    if not foundit:
        foundit = search_method_4("passwords.txt")
    # Still looking? See if it's a single digit
    if not foundit:
        foundit = search_method_1(1)
    # Still looking? See if it's a 2 digit number
    if not foundit:
        foundit = search_method_1(2)
    # Still looking? See if it's a 3 digit number
    if not foundit:
        foundit = search_method_1(3)
    # Still looking? See if it's a 4 digit number
    if not foundit:
        foundit = search_method_1(4)
    # Still looking? Use our rotary wheel simulation up to 6 wheels.
    # This should take care of any 5 digit number as well as letter
    # combinations up to 6 characters
    if not foundit:
        foundit = search_method_2(6)
    # Still looking? Try 7 digit numbers
    if not foundit:
        foundit = search_method_1(7)
    # Still looking? Try 8 digit numbers
    if not foundit:
        foundit = search_method_1(8)
    seconds = time.time()-overallstart
    # When testing this project, some users reported that the next lines of code reported
    # an error when Python tried to divide by zero. On those machines, the clock seems
    # to think that the seconds calculation just above gave us "zero" seconds which doesn't
    # make any sense. To avoid the crash though, we'll test for that case and avoid the
    # problem.
    if (seconds < 0.00001):
        print ("The total search for all methods took "+make_human_readable(seconds)+" seconds and "+make_human_readable(totalguesses)+" guesses.")
        print ("(on some machines, Python doesn't know how long things actually took)")
    else:
        print ("The total search for all methods took "+make_human_readable(seconds)+" seconds and "+make_human_readable(totalguesses)+" guesses.("+make_human_readable(totalguesses/seconds)+" guesses per second)")

    if foundit:
        if (6 == which_password):
            print("Wow! Be sure to confirm your find at http://www.sciencebuddies.org/science-fair-projects/project_ideas/CompSci_p046/PasswordCrack.shtml")
        elif (0 == which_password):  # The Science Buddies website can't confirm passwords you added yourself
            print ("Your algorithm correctly guessed the password you entered. Try some others or see if you can make it guess faster.")
        else:
            print("You can confirm your find at http://www.sciencebuddies.org/science-fair-projects/project_ideas/CompSci_p046/PasswordCrack.shtml")

print ("Science Buddies: How Easily Can Your password Be Hacked?")
if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))



Please write back if you have other questions.

Howard

tedbates
Posts: 4
Joined: Thu Apr 07, 2016 4:23 pm
Occupation: Parent

Re: crack2.py Python question...

Postby tedbates » Fri Apr 08, 2016 6:40 pm

HowardE,

Thanks for the reply! Before I posted here, I used len() myself when I changed the size of the wheel.

One of the things I did was change the passwords.txt file to one that has over 100k words in it. I think that my main problem was that method 4 uses 2 words at a time from the passwords.txt file, and my new list is about 200 times larger than the original. So I moved the wheel method up to the second position in the test and that did the trick. Now the program uses the faster tests first and the slower test last. Right now I'm trying to get it to figure out a 5 letter word with the first letter capital and with punctuation on the end. It's giving my laptop a heck of a workout but I think it will find it.

I have set the program up so that it only uses password0. I made it so the kids can enter a password into a text file and save it. When the program is started up, it prompts you to hit the "enter" key to start, then it reads the password out of the text file and tries to find it. I think that's a lot easier than having the kids enter it directly into the code.

Right now I'm trying to figure out how to get the program to clear the screen after a prompt. Thanks for your help, I think that along with dinner and a small break really helped me out!

Thanks again!
Ted

HowardE
Posts: 496
Joined: Thu Nov 20, 2014 1:35 pm
Occupation: Science Buddies content developer

Re: crack2.py Python question...

Postby HowardE » Sat Apr 09, 2016 6:56 am

Ted-

That has to take quite a while with 100K words - then after it checks all of those once, the two-word version is 100K * 100K * the punctuation. One of the strategies then is selecting a test order so that you can find a password more quickly.

When you talk to students about the math here, the numbers get big when you take into account that so many sites require 8 characters, one capital and a special character. So I can't use "cow" because it's too short, but "cow!barn" is okay if I make it "cOw!bArn"." The wheel test will find that eventually with the additional punctuation. Your list of words still won't find it unless you thought to try the words with the vowels capitalized. Someone else might decide to capitalize the third letter of each, so theirs might be "coW!baRn".

I like your modification to just let students type in a word. I've also heard from other students doing this that they put several words in a file and let the program run when they went off to school. Another student modified the program so that none of the passwords used the MD5 hashes and they could just store a bunch as strings and loop through those.

One way to clear the screen is to print out a whole bunch of blank lines. For instance:

Code: Select all

clear_screen = '\n' * 80

# Then to clear the screen:

print(clear_screen)


I hope you and the kids are having fun even though your poor laptop is doing all the heavy lifting. :)

Howard

tedbates
Posts: 4
Joined: Thu Apr 07, 2016 4:23 pm
Occupation: Parent

Re: crack2.py Python question...

Postby tedbates » Sat Apr 09, 2016 7:53 am

The large dictionary list is really only worthwhile if the password entered exactly matches one of the words in the list. If it doesn't and it moves to method 3, then you are in for a long, long wait. I'm going to reduce the size of the file (maybe to 1k words) and also arrange the search order differently so it hopefully speeds things up a little bit.

I was wondering...would there be any advantage to writing a search method that splits the word being tested into 2 separate parts? I was thinking that each smaller part would be easier to match, and once the method matched both parts it would be easy to combine them back into one word and print the output. It's just a thought but I might try that and see how it goes. My thought is, as an example, if you had an 8 digit password, it would be like checking two 4 word passwords...surely that would be faster?

What do you think?

HowardE
Posts: 496
Joined: Thu Nov 20, 2014 1:35 pm
Occupation: Science Buddies content developer

Re: crack2.py Python question...

Postby HowardE » Sat Apr 09, 2016 10:14 am

I did a little math on my relatively fast Windows machine and with a list of 100K words, the 10 billion tests it would have to make before failing would take about 3.5 hours minimum. That method only works for the simple case where people paste together two common words anyway, and completely fails to account for capitalizing letters.

You might give your algorithm a try but I'm not sure how it can work. If my password is "television", you're suggesting it first find "tele" and then "vision"? In a real passworded system, your entry is either right or it isn't. Assuming that the program is trying to see if you guessed "television", the word "tele" will fail and so will "vision". If the matching algorithm did allow for partial matches by doing string comparisons it might work - but in the real world things are done more like the MD5 hashing.

When you log into your web email, the browser takes the password you type and does some sort of hashing on it. It's very often some salted hash (characters are added so that it's not just a straight MD5) or it's a challenge (the host sends your browser some random gibberish which is combined with your password into new gibberish) and the resulting collection of chopped up data goes back to the host. The host knows your real password and what the random gibberish was so it can tell if you're right. With either method, anyone spying on the transaction won't be able to just resend the same data and sneak in.

One point of the exercise is to help drive home the importance of using good, long, semi-odd passwords. The other point is for you to be able to try out new methods of guessing them. Give your algorithm a try and see how it goes with the plain text password0. If that works faster, how would you apply it to passwords 1-6? Also, you should be aware that the program as supplied will figure out what passwords 1 through 5 are. It won't guess 6 without some help. If you want to try your hand at some new methods, give #6 a try. Some of the issues you raised are the right ones to crack #6 and you'd be the first one to have done it. -- if you do though, please don't post it or your solution here.

Howard


Return to “Grades K-5: Math and Computer Science”