Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate a good salt - Is my function secure enough?

Tags:

security

php

salt

Here's the function I'm using to generate random salts:

function generateRandomString($nbLetters){     $randString="";     $charUniverse="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";     for($i=0; $i<$nbLetters; $i++){        $randInt=rand(0,61);         $randChar=$charUniverse[$randInt];         $randString=$randomString.$randChar;     }     return $randomString; } 

This is for a non commercial website. It's only used to generate the salt (to be stored in the db and used along with the user submitted pw for hashing).

Is this appropriate? Should I use a larger subset of characters, and if so is there an easy way to do that in PHP?

like image 524
JDelage Avatar asked Nov 04 '10 17:11

JDelage


People also ask

How are salt values generated?

According to OWASP Guidelines, a salt is a value generated by a cryptographically secure function that is added to the input of hash functions to create unique hashes for every input, regardless of the input not being unique.

What is salting security?

Password salting is a technique to protect passwords stored in databases by adding a string of 32 or more characters and then hashing them. Salting prevents hackers who breach an enterprise environment from reverse-engineering passwords and stealing them from the database.

Why does salt improve security?

Using ten different salts increases the security of hashed passwords by increasing the computational power required to generate lookup tables by a factor of ten. If the salt is stored separately from a password, it also makes it challenging for an attacker to reverse engineer a password.

How does using a salt help us store the user's passwords more securely?

Salting your passwords helps prevent attacks, such as hash table attacks, by forcing hackers to re-compute the hash values and using the salts for each user. A cryptographic salt is made using random bits added to every password instance before hashing it, making your password strong and secure.


2 Answers

If you are hashing passwords, you should use a modern hashing algorithm that does not require you to generate your own salt. Using weak hashing algorithms presents a danger to both you and your users. My original answer was written eight years ago. Times have changed, and password hashing is a lot easier now.

You should always use built in functions to hash/check passwords. Using your own algorithms at any point introduces a huge amount of unnecessary risk.

For PHP, consider using password_hash(), with the PASSWORD_BCRYPT algorithm. There is no need to provide your own salt.

Below is my original answer, for posterity:


Warning: The following implementation does not produce an unpredictable salt, as per the documentation for uniqid.

From the php sha1 page:

$salt = uniqid(mt_rand(), true); 

This looks simpler, and more effective (since each is unique) than what you have proposed.

like image 76
fredley Avatar answered Oct 05 '22 15:10

fredley


If you're on Linux, /dev/urandom is probably your best source of randomness. It's supplied by the OS itself, so it's guaranteed to be much more reliable than any PHP built-in function.

$fp = fopen('/dev/urandom', 'r'); $randomString = fread($fp, 32); fclose($fp); 

This will give you 32 bytes of random blob. You'll probably want to pass this through something like base64_encode() to make it legible. No need to juggle characters yourself.

Edit 2014: In PHP 5.3 and above, openssl_random_pseudo_bytes() is the easiest way to get a bunch of random bytes. On *nix systems, it uses /dev/urandom behind the scenes. On Windows systems, it uses a different algorithm that is built into the OpenSSL library.

Related: https://security.stackexchange.com/questions/26206

Related: should i use urandom or openssl_random_pseudo_bytes?

like image 39
kijin Avatar answered Oct 05 '22 17:10

kijin