TalkPHP

TalkPHP (http://www.talkphp.com/forums.php)
-   Advanced PHP Programming (http://www.talkphp.com/advanced-php-programming/)
-   -   Best way to use salts? (http://www.talkphp.com/advanced-php-programming/4901-best-way-use-salts.html)

adamdecaf 08-26-2009 11:38 PM

Best way to use salts?
 
I've been wondering this for a while.
  1. The longer the salt the better, right?
  2. What is the best way to use a salt?**

** -
Which way would be best?
PHP Code:

$pw $_POST['pass'];
$salt gen_salt(16); // Function to create a random string of [a-zA-Z0-9{Plus symbols}].
$salt_big gen_salt(32);

// First
$pass sha1($salt $pw $salt);

// Second
$pass sha1(substr($salt08) . $pw substr($salt98));

// Third
$pass sha1($salt_big $pw $salt_big);

// Fourth
$pass sha1(substr($salt_big016) . $pw substr($salt_big1716));

// Fifth
// Note, $mcyrpt would be a class that has the mcrypt() encryptions.
$pass sha1($salt $mcrypt->blowfish($pw) . $salt);
$pass sha1($mcrypt->blowfish($salt) . $mcrypt->blowfish($pw) . $mcrypt->blowfish($salt)); 

Or is there some even better way?

Village Idiot 08-27-2009 12:00 AM

1. Not necessarily. Salts have to turn a string no matter how small into a string (well, base-16 number in md5's and sha1's case) of a given size. The fewer characters the string is the more values overlap, but the larger the string is the more patterns it reveals that can allow it to be reverse-engineered.Keep in mind that these hashing functions are all advanced mathematical algorithms.

2. In a closed source app, there is no best way. Just attach something anywhere on the string and it will throw the entire hash out of whack.

adamdecaf 08-27-2009 12:23 AM

Alright, thanks.

eStrategy 08-27-2009 04:34 PM

In the case of a user auth class you could randomly generate a salt for each user at registration and store it in their database record, so the salt is different for each user. Assuming your database is secure it will now be a massive challenge for anyone to work out your encyption technique....

Just an idea, any thoughts?

adamdecaf 08-27-2009 10:54 PM

Quote:

Originally Posted by eStrategy (Post 28121)
In the case of a user auth class you could randomly generate a salt for each user at registration and store it in their database record, so the salt is different for each user. Assuming your database is secure it will now be a massive challenge for anyone to work out your encyption technique....

Just an idea, any thoughts?

I had already gotten past this, I was thinking of using the password that the user entered as a seed for the random number generator. (Convert the pw to base9, then srand($seed))

After that I would use a randomly assigned (shuffled) assortment of [a-z0-9(symbols)] to use in conjunction with a hash to provide a secure string which can be reproduced (with the correct PW) and doesn't contain the PW. (So if they do crack the hash they would have to crack several random number generations, then pretty much guess at the original PW).

The trouble is then what comes with really secure or insecure PW's? Could/Should they be strengthened or weakened before the assignment, do they alter the theoretical complexity of the hash?

*EDIT* Crap! There would be no way to validate a random string generated from the numerical value of the entered PW, it would be the seed for a PRNG. Therefore ever changing! Scrap that..

eStrategy 08-28-2009 08:06 AM

Yeah you really need to be able to retive the value of the salt for each logon which is why I suggested storing it in database.

I would have thought something like sha1(md5($password)), $salt); would be secure enough wouldn't it?

Village Idiot 08-28-2009 07:01 PM

Quote:

Originally Posted by eStrategy (Post 28146)
Yeah you really need to be able to retive the value of the salt for each logon which is why I suggested storing it in database.

I would have thought something like sha1(md5($password)), $salt); would be secure enough wouldn't it?

There is no advantage in double hashing, in fact it is less secure to do it that way. This is because there are fewer combination of MD5 outputs than possible input strings. MD5 also outputs a base-16 number, so certain characteristics are a given. This can narrow down attacks a lot. A cracker who find out you pass it through MD5 first will know for a fact that it only contains a-f and 0-9, it is also always 32 digits. Although realistically it won't make too much of a difference.

eStrategy 08-31-2009 11:20 AM

Fair point ^^ I reasoned that in most cases the MD5 output would be a lot longer and therefore more complex then the input string, for example a 6 char password vs an MD5 string.

Village Idiot 08-31-2009 02:00 PM

Quote:

Originally Posted by eStrategy (Post 28206)
Fair point ^^ I reasoned that in most cases the MD5 output would be a lot longer and therefore more complex then the input string, for example a 6 char password vs an MD5 string.

Always do hash your password inputs, but don't go crazy with it. MD5 and SHA1 both have been considered insecure for years now by the government. They both have high collision rates on top of that. Although SHA1 has not yet been cracked.

Rainbow tables can us used against either one easily, but even a simple salt makes those useless.

gamer13 09-01-2009 01:42 PM

Mostly I use this technique:

PHP Code:

<?php
function customHashFunction($password)
{
    return 
md5(pack('H*'md5($password)) . $password);
}

It generates a fairly strong salted md5 hash, because the pack-function returns a low-valued ASCII code, which might not even be printable (values below ASCII 32, which is a space).

Village Idiot 09-01-2009 03:18 PM

Quote:

Originally Posted by gamer13 (Post 28236)
Mostly I use this technique:

PHP Code:

<?php
function customHashFunction($password)
{
    return 
md5(pack('H*'md5($password)) . $password);
}

It generates a fairly strong salted md5 hash, because the pack-function returns a low-valued ASCII code, which might not even be printable (values below ASCII 32, which is a space).

That adds no more security and any other salt. Packing it merely scrambles the value in a known (and reversible) way before hashing it.

gamer13 09-01-2009 03:23 PM

Why not? Could you explain that?

Village Idiot 09-01-2009 03:25 PM

Packing it merely scrambles the value in a known (and reversible) way before hashing it. This does not add any more security than adding a simple value to the hash because the values can't be reverse engineered either way.

gamer13 09-01-2009 03:30 PM

Quote:

Originally Posted by Village Idiot (Post 28244)
Packing it merely scrambles the value in a known (and reversible) way before hashing it. This does not add any more security than adding a simple value to the hash because the values can't be reverse engineered either way.

True, but still it's kind of better than using a-zA-Z0-9 in your salt. I mean, try to brute-force a hash with a bit with the ASCII value of 20. But still... there is a big risk there is a collision with a more simple salt.

Village Idiot 09-01-2009 03:35 PM

Quote:

Originally Posted by gamer13 (Post 28245)
True, but still it's kind of better than using a-zA-Z0-9 in your salt. I mean, try to brute-force a hash with a bit with the ASCII value of 20. But still... there is a big risk there is a collision with a more simple salt.

MD5 will always output a base-16 number, so the criteria it could meet does not change one bit when you scramble the value first. If you are going to brute force MD5, you have to start from 0000000.... and end at ffffff... because the values are not reversible and near values do not resemble each other ("hello" and "Hello." are completely different).

How is there a bigger risk if collision with a simple salt?

gamer13 09-01-2009 06:33 PM

Quote:

Originally Posted by Village Idiot (Post 28246)
MD5 will always output a base-16 number, so the criteria it could meet does not change one bit when you scramble the value first. If you are going to brute force MD5, you have to start from 0000000.... and end at ffffff... because the values are not reversible and near values do not resemble each other ("hello" and "Hello." are completely different).

How is there a bigger risk if collision with a simple salt?

Now, that's not true about the brute-forcing. Normally you start with the most common signs varying from the ASCII code 32 (space) until 126 (~). Everything else is not being used (yet) in the common brute-force tools. For instance they start with aaaaaaa, aaaaaab and so on. Normally they don't start with NULNULNULNULNUL.

Using the following code:
PHP Code:

<?php

$salt 
pack('H*'md5('Mysecretpassword'));

you will create this kind of salt:
Quote:

5]~gRF—¿ œÁ¶Ô
Which is with ord(): ord(53) ord(93) ord(22) ord(126) ord(103) ord(82) ord(70) ord(151) ord(191) ord(13) ord(4) ord(156) ord(193) ord(182) ord(212) ord(14)
which is way tougher to brute-force than a salt like:
Quote:

sf(!_$fw(#(*&*(#)@
because you use rare ASCII signs/representations.

About the risk with a simple salt: That's not what I meant :) I mean, there is always a risk that there occurs a collision.

Village Idiot 09-01-2009 06:45 PM

Since MD5 doesn't leave a footprint when you salt, any salt will make reverse engineering measures pointless. The only way they can get past a salt it to guess exactly where it was in the string and its exact value. Which is practically impossible when you don't know the original string.

It in high theory is harder to guess a salt that long and complex, but for all practical purposes it is pointless.

Edit: a quick mathematical layout
A normal salt with only letters, numbers and punctuation marks that is twelve characters long has approximately 12^51 (~1.1x10^55) possible combination. While yours would have much higher number like 45^70 (~ 5.3x10^115).

At one million guesses per second, it would take a computer 3.5x10^41 years to guess the plain salt. Yours would take 1.7x10^102. Neither of these account for the fact that the location is unknown (meaning each possible location is another one of these) and you cant verify your finding is correct without the original password to compare it against.

It would take far less time to brute force the password itself opposed to reversing the hash.

gamer13 09-01-2009 07:08 PM

True, totally true. :)


All times are GMT. The time now is 09:19 PM.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0