Blaine
Blaine

Reputation: 829

Ultimate password salt

So recently I have been doing tons of research on how to secure passwords. I believe I understand the basics of it. As such I am attempting to write my own function to secure a password in php.

But I am somewhat confused when it comes to salting a password. We create a random unique salt and append it to a password and then hash it, and finally store the unhashed salt and hashed password/salt combination together in the database. This increases the search space of the hacker if he obtains access to the database and our hashed passwords.

So this seems like complete overkill of security, but everywhere I see the salt is always appended to the front or back of the password anyways. So looking at a SINGLE user's password this unique salt doesn't affect the search space does it? Although since each user has a unique salt the overall search space of EVERY user is dramatically increased.

Wouldn't it be more secure to create an algorithm that inserts the salt to a predictable, semi-random place in the password such as the length of the username/2? For example here is the steps of my proposed securing function:

Create a random salt
take username length %(mod) password length
insert the salt at the spot determined
hash

Example run:

random salt = 12345
len("imauserwithalongname") % len("mypass") = 2
valueToHash = my12345pass

Now our cracker has no idea where to put the salt without seeing our php/source, which (correct me if I am wrong) is much harder to gain access to than the database.

Also I know security should depend on the security of the key not secrecy of the algorithm, however I see nothing wrong with adding layers based on it, as long as the entire system does not depend on secrecy of the algorithm.

EDIT: Would doing this dramatically increase the search space of a cracker?

And what if we placed the salt in a place that depended on the length of the password, would that not destroy the purpose of using dictionary attacks, even on a per user basis?

Upvotes: 2

Views: 346

Answers (4)

martinstoeckli
martinstoeckli

Reputation: 24141

I think you misunderstood the purpose of the salt. The salt does not increase the search space for an attacker, after all it is stored plaintext with the hash-value. The purpose of a salt is, that an attacker cannot build one single rainbowtable, and then retrieve all stored passwords.

If you would append the same salt to every password, then the attacker cannot simply use an existing precalculated rainbow-table from the internet, he has to build a new rainbow-table for exactly this salt (existing rainbow-tables will contain passwords like "horse", but not passwords like horse8ze*w398dhek3+qmxno0). Unfortunately this single rainbow-table can then be used to get all passwords.

So we use a unique salt for every password. An attacker would have to build a separate rainbow-table for each password now, but why should he continue with building the table, when he already found a match (?), he cannot reuse the table later for other passwords. In other words, brute-force is faster than building a rainbow-table, so we made rainbow-tables useless.

So the salt should be unique for each password and if possible it should be unpredictable. Those criterias are difficult to fulfill with a deterministic computer, the best you can do is, to use the random source of the operating system to build the salts. Good hash algorithms for passwords like BCrypt and PBKDF2 repeat the hashing to become slow, and combine password and original salt in each iteration. It is not just a concatenation of password + salt.

Your idea about putting the salt somewhere secret does add a secret (where is the salt?), that will work as long as the attacker doesnt know your code. Getting the database (SQL-injection) is indeed easier than gaining access to the code, but the same goal can be achieved much easier with a pepper.

I tried to sum up this in a tutorial, maybe you want to have a look at it.

Upvotes: 0

lll
lll

Reputation: 12889

As such I am attempting to write my own function to secure a password in php.

Woah woah, hold it right there.

There's a saying passed down from cryptographers to us mere mortals which has held true for many many years. The saying goes like this:

Do not invent your own crypto.

Say it out loud, then say it again.

I know you're only trying to secure your passwords, but I had to get that out of the way. There are lots and lots of tried and tested methods to do what you want to achieve.

I appreciate you've done some research, but the internet is full of terrible terrible information, so I'm going to point you towards some useful articles.

A nice short list.

Here's some keywords to help you.

  • Bcrypt
  • Scrypt (someone please unstrike this when PHP supports it)

Again a very short list.

To address your specific concern. Salts are not needed to be kept private, as you say they are designed to stop attackers precomputing tables of valid password/hash combinations. However if you use a weak hashing algorithm they lose their value very quickly.

Security through obscurity is not as great as it seems. If a hacker gains access to your DB, the odds are quite high that they will also gain access to your filesystem. If they gain access to your source your custom method of storing passwords is a moot point.

In summary, custom algorithm + weak hash = insecure.

Instead you want to use tried and tested key derivation functions / key strengthening algorithms.

These are designed to make the computer work really hard to generate the hash, and makes it very difficult for an attacker to brute force a password.

Bcrypt stores the salt next to the password, and is proven to be very secure. Secure enough in fact that it is currently the recommended way to hash passwords by security experts.

In PHP 5.5 a simple password hashing API has been introduced based on Bcrypt, and for versions under 5.5 there is a password hashing compatibility library that does exactly the same thing.

That should be enough for you.

Upvotes: 1

Explosion Pills
Explosion Pills

Reputation: 191789

Inserting the salt in a different spot doesn't increase the search space. If you are using a random salt for each user, a hacker does not know what each salt is per user anyway. The knowledge of its position in the unhashed string doesn't matter.

Use bcrypt or PBKDF2. Both algorithms enforce a salt and number of cycles. If you're patient enough, PHP 5.5 will just let you do password_hash($password).

Upvotes: 3

ldionmarcil
ldionmarcil

Reputation: 150

I personally think you're overdoing it. The most efficient way to salt a hash would be to have a dynamic, record-specif one AND a static one stored in a read-only file on the system. This is a very efficient yet secure way of salting hashes.

Upvotes: 0

Related Questions