mysql icon
30th
Jun 09

MD5 and SHA1 “Decrypting” with PHP / MySQL

Posted Tuesday 30th June 2009
This article may be old and/or out-dated
The reference being viewed was created as a redirect from an old post. The content may be out-of-date, inaccurate and/or old.
In this reference we’re going to look at how to “decrypt” (or more accurately “collide”) MD5 and SHA1 hashes by creating a resource of pre-hashed words.

We will be using PHP and MySQL to create a hash table and will also look at some simple methods to further tighten hashes for a website.

1. Creating the Hashes

We will be creating our hashes by using PHP’s MD5 and SHA1 functions on a word list. Each individual word from the dictionary file will be hashed and put into a MySQL database table.

The power, size and amount of hashed passwords we are going to create will depend entirely upon the word list that will be used. The more words and word variations the more hashed words you’ll have at your disposal.

The MD5/SHA1 decrypter on this website uses a very simple English word list (the Websters Dictionary) which you can download from the bottom of this Packet Storm page. It’s a single word dictionary that would in no way be useful in a real scenario but is more than adequate for a reference like this (and a very limited decrypter in general).

2. Preparing the Database Table

Remember that the bigger the word list you use the bigger your table and database in general will be. Too many field entries will result in extremely slow queries so bare that in mind. You’ll also want to, for testing purposes, do this locally and not on a remote server.

Below is our basic MySQL table. It contains a column for the entry id, input string and md5/sha1 hashes.

1
2
3
4
5
6
7
CREATE TABLE hash_table (
id int(255) AUTO_INCREMENT,
string varchar(255),
md5_hash varchar(255),
sha1_hash varchar(255),
PRIMARY KEY(id)
);

3. Adding Hashes to the Table

Now that the table is prepared connect to the database with PHP and hash each word line by line. Below is a simple example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
mysql_connect('localhost', 'username', 'password') or die (mysql_error());
mysql_select_db('database') or die (mysql_error());
 
// Open the file for reading
$file_handle = @fopen('websters-dictionary', 'r');
 
if ($file_handle)
{
    while(!feof($file_handle))
    {
        // Remove whitespaces, line breaks etc
        $buffer = trim(fgets($file_handle, 255));
 
        // Change the case sensitivity
        if (strlen($buffer) > 1)
        {
            $word_version[0] = strtoupper($buffer);
            $word_version[1] = strtolower($buffer);
            $word_version[2] = ucfirst($buffer);
        }
        else
        {
            $word_version[0] = strtoupper($buffer);
            $word_version[1] = strtolower($buffer);
        }
 
        // Cycle through the word array
        for ($i = 0; $i < sizeof($word_version); $i++)
        {
            $q = 'INSERT INTO hash_table 
                    (string, md5_hash, sha1_hash) 
                    VALUES 
                    ("'.$word_version[$i].'", "'.md5($word_version[$i]).'",
                    "'.sha1($word_version[$i]).'")';
 
            mysql_query($q) or die (mysql_error());
        }
 
        // Clear array from memory
        unset($word_version);
    }
}
else
{
    echo "Error opening file...";
}
?>

Using the script above, or something similar, will populate a list of hashes for common English words. With some minor adjustments you can easily expand on the amount of hashes and variations that you want available.

You can now perform database queries and retrieve hashes for every word provided in the dictionary. This should be an insight into how easy it is to find out pure hashes. Obfuscating hashes (for example hashing a hashed string) has a very limited effect and isn’t recommended. Next we take a look at strengthening hashes for websites.

4. Strengthening Passwords

The first step to strengthening a hash is to strengthen the password itself. A password like “apple” isn’t recommended for fairly obvious reasons. Creating an alphanumeric password, such as “apple21″ is better. Even better you could check or enforce case sensitivity so that the password becomes “Apple21″.

People will naturally provide bad passwords so take some logical measures to ensure they provide a good one. A case sensitive, alphanumeric password longer than 7 characters in length should be the bare minimum. Don’t, however, change peoples passwords for them automatically!

In a nutshell: a better password creates a better hash.

Another popular method is to add a pinch of salt. The method for adding salt is to concatenate a password string with a seperate string. For example:

1
2
3
4
5
6
7
8
<?php
$salt = 'salt';
$password = 'ApPLe87';
 
$salt_password = md5($salt.$password);
 
echo $salt_password;
?>

To find the hash you must have (or find) the salt value and know where to concatenate it to the password. To know the salt you can either have it contained within your database table beside the password or inside a PHP script.

If you add the salt value take into consideration that should your database be compromised the salt added to the hash is rendered useless. It’s good practice to have a unique salt value in both the database and PHP script in case either one is compromised.

A unique pinch of salt (for each hash) is highly recommended. You can further the unique hash by salting it on something related to the user such as their e-mail address or username. For example:

1
2
3
4
<?php
$password = 'ApPLe87';
$salt_password = md5($email.$password);
?>

By adding salt the password hash has immediately been strengthened. A good salt value is just as important as a good password to begin with.

Security is an ongoing battle that will never end. By strengthening a password hash you are not defeating a cracker you are just making their job a lot more difficult and time consuming. And please, enforce things upon your site users in moderation!

Bookmark or share this page:

SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon

MSN Contact: contact [at] danielgibbs.net



2 Comments

  1. William 17 December 2009 5:26 pm

    This is great, but how do I get the information back out as text?

  2. Manjunatha 5 July 2011 7:24 am

    I need a php code for decryption MD5 salt password. Would anybody who know that can post it to my mail.

TrackBack URL

Leave a comment