Jump to content

Uncrypting passwords


reportingsjr
 Share

Recommended Posts

Ok, I am making a textbased game and I am having some issues with securing the passwords for usernames. I have it so when you register your name get encrypted with this code and sent to the database:

$query2 = "INSERT INTO `g_users` VALUES ('" . $_POST['uname'] . "', '" . crypt($_POST['pwd']) . "', '" . $_POST['email'] . "')";

Now, it will create an encrypted password and it shows up in database and such. But how do I get it to pull back out uncrypted from the MySQL database?!? I have this code for a login page and its not exactly working:

$query = "SELECT *  FROM `g_users` WHERE `name` = '" . $_POST['uname'] . "'   AND `password` = SHA1('" . $_POST['pwd'] . "')";

I looked at some post and the functions but I couldnt get anything from them.Help appreciated!For now I am having uncrypted passwords in the MySQL database.. its not open yet anyways.

Link to comment
Share on other sites

Unfortunately, encrypting passwords mean they'd get permanentaly changed.If decrypting would exist, the encrypting would not have any function, as anyone would be able to decrypt :)If you choose to encrypt passwords, they cannot be reviewed afterwards, the only use of it then, is to be able to validate user input that also gets encrypted, against the already encrypted password in your database :)In short, decrypting functions do not exist, due to security leaks :)Next, the following string can be smaller and less quoting complicated, and you may encrypt with SQL itself instead of by PHP:

$query2 = "INSERT INTO `g_users` VALUES ('" . $_POST['uname'] . "', '" . crypt($_POST['pwd']) . "', '" . $_POST['email'] . "')";
This results in the same:
$query2 = "INSERT INTO `g_users` VALUES ('{$_POST['uname']}', password('{$_POST['pwd']}'), '{$_POST['email']}')";
Edited by Dan The Prof
Link to comment
Share on other sites

So, would it still make the same crypted password if you crypted the password going to login.php?so if the mysql stored password is: $09ihdsoiaa3k34845 but the entered password is 'myname' when the person tried to login with the password 'myname' and the page encrypted it would the new encryption be $09ihdsoiaa3k24845? So you would just encrypt them both?

Link to comment
Share on other sites

Lets say this will happen:First, the user registeres at your site. The password, "mypass", he puts in, gets encrypted, "q1w2e3r4t5y6", and stored in your database as such.Second, when he tries to log in, the again puts in the same password, "mypass". The processor that handles the logins, encrypts this login info too, "q1w2e3r4t5y6", and validates the new data with the stored data. It is correct, so login was succesfull. If not, he gets redirected :)Check my above post, I edited.

Link to comment
Share on other sites

Dan, I have a question. Isnt there a code for each letter-symbol typed then? because to create the same cryption it would need to have a code, or it would be randomly generated. so If someone got the code for this couldnt they create like a javascript page to decrypt for them? And thanks dan and pulp, its all sorted out now.

Link to comment
Share on other sites

Each character you type has a corresponding numerical code somewhere. But the result of a hashing function is not decryptable. Consider this. You can take the entire text of Homer's Odyssey and run it through a hashing algorithm like sha1 or md5. The sha1 algorithm will produce a 40-character hash. There is no possible way to decrypt that 40-character hash into the 17,000 word Odyssey. It's simply not possible. You can't store the Odyssey in 40 bytes. I believe the NSA has certified that SHA-1 is secure enough for US government use, although they have moved on to SHA-256 and SHA-384. The "S" in "SHA", by the way, stands for "secure".Also, about your question. Because of the way the algorithm works, any specific string will always produce the same hash. You can run the string "admin" through sha1 100 times, and it will always produce the hash "d033e22ae348aeb5660fc2140aec35850c4da997". This is a requirement of the algorithm, it does not mean there is anyway to decode it. You cannot decode that hash and get "admin" back, it's not possible.

Link to comment
Share on other sites

You could have a look at the RSA method, which does actually not have anything to do with site building, but is all about prime numbers, it proves there is almost no way back from encripting, unless you know the two secret (super mega long) prime numbers :)

Link to comment
Share on other sites

RSA doesnt come under Hashing, RSA is a cyrpto system, Breaking RSA would mean hacking. RSA keys are 1024 to 2048 bits long and prime... [ actually I took a course in Cryptography this semester.. :)]RSA is a two way function, with the private keys we can decrypt. But in Hashing [one way]there is no way back even with the keys used by the hash function.

Link to comment
Share on other sites

Here is also the source code (in JavaScript) for SHA-1. There is a lot of bitshifting and logical arithmetic, but there is no "key" or anything generated. As pulpfiction pointed out, that's a major difference between hashing and encryption.

/* * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined * in FIPS PUB 180-1 * Version 2.1 Copyright Paul Johnston 2000 - 2002. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See [url="http://pajhome.org.uk/crypt/md5"]http://pajhome.org.uk/crypt/md5[/url] for details. *//* * Configurable variables. You may need to tweak these to be compatible with * the server-side, but the defaults work in most cases. */var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      *//* * These are the functions you'll usually want to call * They take string arguments and return either hex or base-64 encoded strings */function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));}function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}/* * Perform a simple self-test to see if the VM is working */function sha1_vm_test(){  return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";}/* * Calculate the SHA-1 of an array of big-endian words, and a bit length */function core_sha1(x, len){  /* append padding */  x[len >> 5] |= 0x80 << (24 - len % 32);  x[((len + 64 >> 9) << 4) + 15] = len;  var w = Array(80);  var a =  1732584193;  var b = -271733879;  var c = -1732584194;  var d =  271733878;  var e = -1009589776;  for(var i = 0; i < x.length; i += 16)  {    var olda = a;    var oldb = b;    var oldc = c;    var oldd = d;    var olde = e;    for(var j = 0; j < 80; j++)    {      if(j < 16) w[j] = x[i + j];      else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);      var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),                       safe_add(safe_add(e, w[j]), sha1_kt(j)));      e = d;      d = c;      c = rol(b, 30);      b = a;      a = t;    }    a = safe_add(a, olda);    b = safe_add(b, oldb);    c = safe_add(c, oldc);    d = safe_add(d, oldd);    e = safe_add(e, olde);  }  return Array(a, b, c, d, e);}/* * Perform the appropriate triplet combination function for the current * iteration */function sha1_ft(t, b, c, d){  if(t < 20) return (b & c) | ((~ & d);  if(t < 40) return b ^ c ^ d;  if(t < 60) return (b & c) | (b & d) | (c & d);  return b ^ c ^ d;}/* * Determine the appropriate additive constant for the current iteration */function sha1_kt(t){  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :         (t < 60) ? -1894007588 : -899497514;}/* * Calculate the HMAC-SHA1 of a key and some data */function core_hmac_sha1(key, data){  var bkey = str2binb(key);  if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);  var ipad = Array(16), opad = Array(16);  for(var i = 0; i < 16; i++)   {    ipad[i] = bkey[i] ^ 0x36363636;    opad[i] = bkey[i] ^ 0x5C5C5C5C;  }  var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);  return core_sha1(opad.concat(hash), 512 + 160);}/* * Add integers, wrapping at 2^32. This uses 16-bit operations internally * to work around bugs in some JS interpreters. */function safe_add(x, y){  var lsw = (x & 0xFFFF) + (y & 0xFFFF);  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);  return (msw << 16) | (lsw & 0xFFFF);}/* * Bitwise rotate a 32-bit number to the left. */function rol(num, cnt){  return (num << cnt) | (num >>> (32 - cnt));}/* * Convert an 8-bit or 16-bit string to an array of big-endian words * In 8-bit function, characters >255 have their hi-byte silently ignored. */function str2binb(str){  var bin = Array();  var mask = (1 << chrsz) - 1;  for(var i = 0; i < str.length * chrsz; i += chrsz)    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32);  return bin;}/* * Convert an array of big-endian words to a string */function binb2str(bin){  var str = "";  var mask = (1 << chrsz) - 1;  for(var i = 0; i < bin.length * 32; i += chrsz)    str += String.fromCharCode((bin[i>>5] >>> (24 - i%32)) & mask);  return str;}/* * Convert an array of big-endian words to a hex string. */function binb2hex(binarray){  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";  var str = "";  for(var i = 0; i < binarray.length * 4; i++)  {    str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +           hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);  }  return str;}/* * Convert an array of big-endian words to a base-64 string */function binb2b64(binarray){  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";  var str = "";  for(var i = 0; i < binarray.length * 4; i += 3)  {    var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)                | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )                |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);    for(var j = 0; j < 4; j++)    {      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);    }  }  return str;}

Link to comment
Share on other sites

When we studied hashing in school, we concentrated on hash tables. Assume you have an array with 20 numbers in it:[7, 45, 68, 12, 87, 48, 26, 38, 96, 14, 64, 56, 27, 47, 18, 5, 61, 9, 67, 19]Now assume that, for whatever reason, you want to store all of these numbers in a 5-element array. Assume that more than 1 number can be stored in each element (each element is a list). The storage array starts with 5 empty elements:0->[]1->[]2->[]3->[]4->[]So, how do you decide which of the 20 numbers goes in each of the 5 array elements? You need a hashing function to execute over each of the 20 numbers, and the hashing function needs to return a number from 0-4 to decide which position to store the number in. A simple hashing function would be modulus, so you can mod each number by 5 to get a value between 0 and 4 (the modulus operator returns the remainder. 11 mod 4 is 3, because once you divide 4 into 11, which goes in two times, the remainder is 3. the modulus operator is usually "%"). So you could do this:7 % 5 = 20->[]1->[]2->[7]3->[]4->[]45 % 5 = 00->[45]1->[]2->[7]3->[]4->[]68 % 5 = 30->[45]1->[]2->[7]3->[68]4->[]12 % 5 = 20->[45]1->[]2->[7, 12]3->[68]4->[]etc.Using hashing functions, you can map a set of many elements to a set of fewer elements. The hashing function above (mod 5) has a domain of only 5 members, but the SHA-1 function returns a 160-bit hash, and so the domain of SHA-1 has 2^160 members, or 1.4615 * 10^48. That's a lot. But whereas here we started with 20 elements to hash, in reality SHA-1 can accept an infinite number of strings to hash, but it will always produce one of the 1.4615 * 10^48 possible 160-bit strings as a result. But since that number is so high, the chances that any 2 strings would result in the same hash is really small.Does that make sense at all?With regard to salt, salts are usually use to guard against a dictionary attack. In a dictionary attack, a program repeatedly tries to log in by trying a dictionary full of common words as possible passwords. If the program knows what the hash is, it can compare that against a dictionary full of known hashes and try to figure out the original un-hashed word (or another word that produces the same hash). So instead of using a dictionary of common words, it uses a dictionary of hashed common words. But if you use a salt, which is some random string that you create somehow (hash the timestamp for example), and then use that salt to hash the password, then figuring out the original password from the known hash is basically impossible. This is what I mean. Instead of this:$pw = $_POST['password'];$database_pw = sha1($pw);mysql_query("INSERT INTO users (password) VALUES ('{$database_pw}')");You might do this:$pw = $_POST['password'];$salt = sha1($_SERVER['REMOTE_ADDR'] . mktime()); //based off user's IP and date$database_pw = sha1($pw . $salt); //salt that passwordmysql_query("INSERT INTO users (password, salt) VALUES ('{$database_pw}', '{$salt}')");Note that you also need to store the salt in the database, and when the user tries to log in you need to do the same thing to encode the password they enter with the salt in their user record, and compare that hash with the password hash in their user record.

Link to comment
Share on other sites

Also, reportingsjr, I noticed that in your original post that you were using both crypt() and sha1(). That's why the password wasn't working, because crypt() and sha1() use different algorithms. You can check here and run both crypt and sha1 and see that they produce different results.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...