2

After hearing that MD5 isn't safe for password storage (MySQL), I decided to use PHP's crypt() with Blowfish (tell me if you know any better algorithms). So I randomly generate a 32-character salt and encrypt a given string. Here's the code:

//Some variables
$text = $_POST['text'];
$salt = "";
$length = 32;
$chars = "abcdefghijklmnopqrstuxyvwzABCDEFGHIJKLMNOPQRSTUXYVWZ123456789";
$numchars = strlen($chars);

//Random string generation
for ($i=0; $i <= $length; $i++)
{
    $index = mt_rand(0, $numchars-1);
    $salt .= $chars[$index];
}

//Encrypt $text using Blowfish
$encrypted = crypt($text, "$2a$12$" . $salt . "$");

The results I've been getting have been really weird... with some configurations much like this one the encrypted result contained multiple dollar sings $ in a row. With this code, $encrypted-- the result-- actually contains the salt it was given, and $encrypted is preceded by the Blowfish indicator $2a$.

My version of PHP supports Blowfish, by the way. Here's an example of a result:

Encrypted "hello"
$encrypted: "$2a$12$az1aszWXtzw9R7Y4Iv97KeUPwcPG9pgx/CAW42F/67X64l60lMvGa"
$salt:             "az1aszWXtzw9R7Y4Iv97KmM6miSXnecKB"

What am I doing wrong? Thanks for your help.

EDIT : Whoa, I just thought of something: Shouldn't I always use the same salt, or should I randomly generate one and store it with each user account in MySQL?

LonelyWebCrawler
  • 2,866
  • 4
  • 37
  • 57
  • Can you post a link to where you heard that md5 isn't safe for password storage? – Mike Purcell Oct 28 '11 at 20:09
  • http://www.php.net/manual/en/faq.passwords.php – LonelyWebCrawler Oct 28 '11 at 20:10
  • @user805556: Thanks, guess it's back to the drawing board for us. – Mike Purcell Oct 28 '11 at 20:13
  • @DigitalPrecision md5 has been "broken" years ago; also, IIRC, collisions have been found in sha1 too, so it also can be considered "broken". A weak md5 hash with no salt is likely to be easily reversed by the huge rainbow tables out there. A salted md5 can be still considered ok, though hashing is just a very,very small part of a site security. – Damien Pirsy Oct 28 '11 at 20:15
  • Why is SHA256 better than Blowfish? – LonelyWebCrawler Oct 28 '11 at 20:15
  • There's nothing wrong with "strange" characters showing up in the encrypted string. It's the difference between having just numbers, just letters, or numbers, letters, and symbols. The latter is much more secure. – Derek Oct 28 '11 at 20:16
  • There are already enough comments here, and [this article is a few years old](http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html), but fwiw: "The problem is that MD5 is fast. So are its modern competitors, like SHA1 and SHA256. Speed is a design goal of a modern secure hash... **Speed is exactly what you don’t want in a password hash function.**" – sdleihssirhc Oct 28 '11 at 20:17
  • Please read the edit of my post. – LonelyWebCrawler Oct 28 '11 at 20:18
  • I've read up a bit and thing you are right wrt using blowfish instead of sha256/sha512, primarily since the algo is slower. http://stackoverflow.com/questions/2235158/php-sha1-vs-md5-vs-sha256-which-to-use-for-a-php-login – hafichuk Oct 28 '11 at 20:23
  • Thanks for the enlightenment on this subject. Informed the dev team about the md5 shortfalls and we will be adjusting accordingly. – Mike Purcell Oct 28 '11 at 20:24
  • Sha256 is **not** better than blowfish. Blowfish is the best algorithm available for PHP at the moment... – ircmaxell Oct 28 '11 at 20:39

2 Answers2

2

Check out http://us2.php.net/crypt, example #3 "Using crypt() with different hash types". In the example output it shows that the salt strings are also part of the encrypted value, so your issue with the salt being part of the encryption appears to be by design.

Mike Purcell
  • 19,847
  • 10
  • 52
  • 89
  • So having the salt partially inside the password poses no security issues? – LonelyWebCrawler Oct 28 '11 at 20:14
  • Do you also recommend SHA256 instead of Blowfish? – LonelyWebCrawler Oct 28 '11 at 20:15
  • 1
    I don't think so, b/c components of the string are being encrypted using the given algorithm (crypt). Also you are going the extra step of randomizing the salt. However this confuses me, b/c salt is usually a static value, if you randomly generate it every time, how do you expect to get matches from the encrypted values you stored in the database? – Mike Purcell Oct 28 '11 at 20:16
  • 1
    Usually you would generate a salt and store it in the database with the user information when the account is created. Unique salt per account reduces the risk to only one account if it's compromised. – hafichuk Oct 28 '11 at 20:21
  • hafichuk is correct, numerous open source projects use this approach such as vbulletin and phpbb. But if someone hacks your database and can view your passwords, they can just as easily view the salts. – Mike Purcell Oct 28 '11 at 20:23
  • Sorry to bother you guys, but I ran across another problem. This is a Blowfish encryption I got: $2a$07$$$$$$$$$$$$$$$$$$$$$$.gY/7XssMMSPuF1Q1MG31mOOUCTGDn/q | Too many dollar signs? – LonelyWebCrawler Oct 28 '11 at 20:26
  • Tough to say, at first appearance yes. What I would do is create an array of 5 words. Step through the array and encrypt each word and see if you notice a pattern with the dollar signs. It might just be an odd coincidence. – Mike Purcell Oct 28 '11 at 20:34
0

You should use randomly generate one and store it with each user account in MySQL Because it is more safer than using the same salt.

Reason is that the salt which is used can be always the 22 characters and the remaining $2a$12$ totally first 28 char which specify by the salt and the rest will be an hash of your password.

Community
  • 1
  • 1
neevan
  • 31
  • 8