How to store this sensitive information? [closed] - php

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
We need to store passwords (real information stored is some very specific business information but can be compared to passwords to simplify the question). The passwords should be hashed/encrypted.
We do not want to be able to read the passwords but to be able to know which users have the same.
What if we crypt() with a CRYPT_BLOWFISH hash using always the same salt?
How can we hash/encrypt the passwords and ensure that if the database is compromised, the attacker will not be able to read or decrypt them?

With passwords you are always looking for hash, you don't want or need to decrypt them. Thus what you are looking for is a strong hashing algorithm, blowfish or SHA512 I would suggest. As for your question of different user password comparison, well that would significantly reduce the overall security of the system.
You want to include a random salt with each password to make it impossible to precalculate the hashes, so even the same password would have a different hash for each user, otherwise an attacker might find out which of the users use the same passwords and use it to their advantage. Using the same salt for every password defeats its purpose and using none allows for usage of rainbow tables, so you will have to sacrifice that particular feature if you want a secure design of the application.
Edit: sorry deleted the comment and posted it as answer
I suppose if you are looking for a compromise you would be looking at a lot of hashing iterations, perhaps with a large random salt common to all passwords. That should ensure that there aren't any already available precalculated tables to use for cracking the passwords and increase the cracking time. Algorithm chaining might also be an option, but you might run into a performance issue if there are a lot of users. Essentially if you still want to be able to compare user passwords, make it time consuming to calculate the hash, which should radically increase the cracking time. Again to stress, this would be a compromise and definitely is not the most efficient and secure way to go around this issue.

It entirely depends on what your business information is. You already have seen, that hashing would be preferable over encryption, because it cannot be decrypted (otherwise you would have asked differently).
The problem why you cannot hash the information like a password, is that the salt would be unique and the hash function would therefore result in uncomparable hashes-values. If we could do without a salt, we could use a hash function for your purpose.
Salting is done, because passwords are normally short textes (people have to remember them). By checking dictionaries or rainbow-tables we could find the original password very fast, but there are no existing rainbow-tables for salt+password textes. To say it differently, very strong passwords with a certain length would not need salting to be safe. If your business information has enough unique information (entropy), you could do the hashing without a salt and use BCrypt or PBKDF2.

You would need a salt and bytes array to store sensitive information. You could then encrypt the pair with a master key stored somewhere else, safely. With 2 phase encryption you can roll your keys as often as need for security purposes. Your application would need to be able to combine the pieces to compare data.

With passwords I and many others on SO and other websites highly recommend Bcrypt; Bcrypt is a computing intensive hashing algorithm, designed to be slow and expensive to brute-force.
You can read more about Bcrypt on an answer here:
How do you use bcrypt for hashing passwords in PHP?
As for comparing the values, you can't with Bcrypt, but you can check if the value is correct.

Related

Password hashing methods

Im creating a PHP based CMS (using MVC architecture). I'd like to hash the user passwords stored in the DB. I have read many artices and tutorials about this topic, but I've faced opposing opinons/points of view and suggestions. Im a bit confused. Im looking for the best way to implement password hashing. These are the concepts/methods I've met:
First of all many people mix up the 1-way hashing and the 2-way encryption. If i'm not mistaken the 2-way encryption is the thing about the assymetric encryption with public-private keypairs, And it is for securing the data and make it only readably by the ones who know the other key (the secret key). So this is what we don't care about now.
PHP provides many functions to making hashes, some of them directly uses a hashing alogrithm on the given data (md5(), sha1(), sha256(), ripemd160() etc.) some of them accepts the given data and a supported algorithm and generates the hash (hash(), hash_init(), hash_hmac() etc.)
What is the difference between the loads of hashing/crypting methods? (hash_pbkdf2(), crypt(), bcrpyt, password_hash() and the others mentioed above)
as I learned it is a good practice to use salts in your hash, but it is a bad idea to hash multiple times (even so many tells it is good). Some functions use salt others use key...
Question 1:
Could someone clarify what is the difference between eg.: md5('myPassword'); and hash('md5', 'myPassword'); (I know md5 is an easy to hack method and is not recommended to use to store passwords)
Question2:
And what is the difference between the key and the salt? So what is the difference between hash_hmac('sha1', 'myPassword', 'HaCK_MeIF_youCAN'); and sha1('myPassword'.'HaCK_MeIF_youCAN');?
(notice that hash_hamc calls its 3rd argument 'key')
Question3:
Is multiple hashing really a bad practice?
Like:
hash = sha512(password)
for i in range(10000):
hash = sha512(hash) + salt
return hash
Question4:
What should be the best method to hash my passwords?
Since this is an important and sensitive issue and I think others not familiar with the topic like me would like to make this hash thing clear and would like to get accurate and reliable answers once and for all, I ask you to answer just in case you are an IT security expert or you have any certification or degree in this topic! (For self-proclaimed security experts who acquired their knowledge on the internet: The fact you have done hundreds of systems/websites with hashed passwords doesn't mean that they are secure!)
And one last request: simple (beginner) webprogrammers aren't aliens nor theoretical mathematicians. So please try to explain in some human-like english :)
There are a lot of questions about password hashing on Stack Exchange already, so this is basically a duplicate question, but as you don't know what to trust I'll give you some pointers.
Re: Question 1: Probably they are just different interfaces for the same code. (I haven't checked though. If you want to be sure put the same input in both and compare the output. Or just look up the documentation or in the source code.)
Re: Question 2: A key is a private piece information that you normally should never publish (except for public keys in asymmetric cryptography). Usually there are no keys in password hashing. A salt is a piece of public information that is random and is meant differentiate your password hashing from every other precomputed hash table in the world. It is the main defense against rainbow tables.
HMAC (basically m,k⟼Hash(k||Hash(k||m)) for the concatenation operation ||) was designed to be a so called message authentication code. It is (ab)used for many other purposes though, because of its versatile design if instantiated with a good cryptographic hash function. In this case using the salt as key and the password as message in HMAC is really not that different from Hash(password||salt).
Re: Question 3: No, it is a good practice. The main attack scenario of password storage is that your database is compromised (and often all password data is published if your are significant enough that people will care). Most non technical folk (and apparently even some with IT background) often reuse their passwords (which is a bad practice even if everyone would get their password hashing strait). Thus with your database breach a lot of accounts of a lot people suddenly have known login information if you save the passwords as plaintext. To prevent this you want to use a oneway function on the passwords. Unfortunately passwords have very few entropy most of the time (because nobody likes to remember cryptographically secure passwords) and thus if you use a fast hashing function you can try out every likely password and compare the hash against the one in the database. As extreme example, lets assume I only use the password cat or dog and you have the sha1 hash of my password: 8f6abfbac8c81b55f9005f7ec09e32d29e40eb40 generated by echo $password | sha1sum. Exercise for the reader: which password have used?
To alleviate this problem you want to use a slow hashing function so that trying out every likely password takes a lot of time. One way to slow down the hashing is to iterate the hashing a few thousand (or even few hundred thousand) times. There are other slow hashing concepts like bcrypt, though, that do not just iterate hashing.
Re: Question 4: An in depth discussion can be found on security.stackexchange.com: https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords . The tl,dr version is CodeInChaos's comment: Just use password_hash, it is mostly fool proof. A resource for the advance topic of pepper in addition to salt can be found here: https://security.stackexchange.com/a/3289/10727 .
I will try to answer some of your questions, but first a word about encryption. The problem of encryption is that it is two-way, the password can be retrieved if you know the key. Storing only a hash (one-way) will protect passwords better, because the passwords cannot be retrieved even if all code (including a key) is known.
Question 1 & 2:
It is important that you avoid all fast hashing algorithms, this includes MD5, SHA*. Because they are so fast, they can be brute-forced too easily. It is e.g. possible to calculate about 8 Giga MD5 hashes per second with common hardware.
Question 2:
A salt should be randomly generated for each password, but is not secret and can be stored plaintext with the password in the database. A key (sometimes called pepper) should be kept secret and is not stored in the database.
Question 3:
Multiple hashing is a good thing, but only if done correctly. Appropriate algorithms like BCrypt and PBKDF2 do it in a safe way, and they have a cost factor that determines the number of iterations. This cost factor can be adapted for future and faster hardware.
Question 4:
At the moment the best you can do is to use the PHP function password_hash() to create a BCrypt hash. There also exists a compatibility pack for earlier versions. I wrote a tutorial about safely storing passwords, where i tried to answer this questions a bit more indepth and in a hopefully understandable form, so you mave have a look at it.

Hashing authentication data in 2013

I am facing the never ending problem How to store passwords in DB?. As far as I read recently there ware a few of the previously considered safe algorithms, which had been marked as insecure. So I am struggling to find a up-to-date resource which describes the ones that are not secure any more.
I was thinking of combining two or three algos, but I remember back in the day it was considered insecure, i.e exposes the hash to attacks. The combination I was thinking of was something like that:
data_h1 = sha256(sha1(data_salt).sha1([username|email]).sha1(data_peper))
data_h2 = sha256(sha1(data_salt).sha1(user_entered_password).sha1(data_pepper))
hmac(
sha512,
data,
sha512(general_salt.data_h1.data_h2.general_pepper)
);
Where data_salt and data_pepper are constants, hard-coded in to the application, but are different than general_salt and general_pepper which are as well hard-coded constants. [username|email] is the value supplied by the user on registration and when logging in, as well as *user_entered_password* (doh!).
Will this compromise security in some way? (if no go to next)
Will there be a major bottleneck due to the hash-o-mania which will be going on in the process of generation? (go to next)
Any recommendations on the approach showed above?
My questions goes for PHP, but will be good to see what will you guys recommend and what will your comments be in general, b`cuz I do think that this is very common task, and many people still use only MD5 or SHA1 (or better yet, storing in plain text).
The main reason not to use SHA-1 or SHA-256 alone for hashing passwords is that
they are fast, relatively speaking. Password authentication is vulnerable to dictionary
attacks and brute-force attacks, since users tend to include common words in their passwords
and use relatively short passwords, making them easier to guess than encryption keys.
Hash functions like bcrypt and PBKDF2 are recommended because they are slow.
They can be tuned to take almost any amount of time; it should take as long as
possible to hash a password without causing unreasonable delay. This will help slow
dictionary attacks and brute force attacks.
However, this is not the only security consideration for password storage.
When "storing" passwords you do not actually store the password, you store its one-way hash. The reason for this is to prevent even someone with access to the system from learning a user's password. The "one way" aspect of the hash means that, while it is possible to create a hash from the plaintext, it is impossible to learn the plaintext from the hash.
In addition, all passwords should be concatenated with salt (a random sequence of digits) before being hashed. The salt value should be stored along with the hash in the database. The salt must be ROW-SPECIFIC, i.e. every password should have its own salt.
Why must hashes be row-specific? Imagine a hacker has somehow obtained a copy of your database. Normally he's up against a pretty big brute force task. If you have only one hash, the hacker can examine all the rows and find rows that occur the most frequently, because the same password + the same salt always renders the same hash. So with this information he can guess that those rows contain commonly-used passwords. He can then use that information to reduce the size of his brute force problem. Or he can try to learn one of those users' passwords and then be able to use that password on any of the other users' accounts that have the same hash. The whole point of the salt is to prevent attacks of that nature.
Use a decent one-way cryptographically secure hash with a user-specific salt. That is the standard means of storing passwords.
The addition of application-specific "pepper" (which is the same every row, and must be cryptographically random and held in a secure location) tranforms the hash into an HMAC (Hash-Based Message Authentication Code), which is even better. If someone knows your hashing algorithm and salt but doesn't know the pepper, he will have a much harder time guessing the password.

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?
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).
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.
Check out ircmaxell's security related
blogs.
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.
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.
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.

How does service salt work? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I want to know how service salt works. I know how to bcrypt password and give each user an unique salt. But I heard there is also another layer you can add by having a service salt. I am just curious how that works. What is the difference between that and an unique salt generated for the user?
Here's where I saw the term service salt: Web Application - Storing a Password
The "service salt" (described as "a sitewide static salt" in the question you cite, and also sometimes called "pepper" in crypto literature) is simply a secret string which is fed to the password hashing algorithm along with the password and the per-user unique salt.
The point of having a "service salt" like that is that, unlike the per-user salt values, the service salt is not stored in the database but somewhere else (typically in a configuration file, or hard-coded into the application). Thus, it protects the passwords against attacks that only compromise the database but don't allow the attacker to access the app configuration. With modern web apps, such an attack scenario is not as unlikely as it might seem; for example, a simple SQL injection attack would often fit this scenario.
One detail to keep in mind is that, unlike the per-user salt, which just needs to be unique and not too easily predictable, the "pepper" actually has to contain a substantial amount of entropy (say, 128 bits) and must be kept secret for it to be of any use.
In any case, including such a secret constant in the password hash calculation is pretty easy, so there's very little reason not to do it: even if your password hashing algorithm doesn't explicitly support it, you can just, say, append the "pepper" to each password.
"The benefit provided by using a salted password is making a lookup
table assisted dictionary attack against the stored values
impractical, provided the salt is large enough. That is, an attacker
would not be able to create a precomputed lookup table (i.e. a rainbow
table) of hashed values (password + salt), because it would take too
much space. A simple dictionary attack is still very possible,
although much slower since it cannot be precomputed."
Source: http://en.wikipedia.org/wiki/Salt_(cryptography)
A salt prevents reverse checks against rainbow tables that are meant to hack passwords easily. The "salt" converts something easily hackable into something more difficult for a hacker to decrypt.
I would highly reccomend that you toy around with this api;
http://www.openwall.com/phpass/
It does all that nitty gritty password generation for you without you needing to be a security expert. Additionally, it has fallbacks built into it to work with older/weaker systems.

Does encrypting a password multiple times really make it more secure? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is “double hashing” a password less secure than just hashing it once?
So, I was reading an article on securing PHP websites and they recommended hashing a password multiple times, in fact, this is a direct quote from the article:
md4(md4(md5(sha1(md4(md5(sha1(sha1($_POST['password']))))))));
Now, personally, I generally use a salted SHA-256 hash on my passwords, because I thought that MD4 and MD5 were no longer secure and that hashing a password multiple times would just put too much strain on a server for no practical benefit. Is that correct?
The direct quote from the article wouldn't work, as there is no md4() function in PHP. And then it wouldn't make sense still.
Normally applying multiple hashing functions wouldn't hurt. But when you go from sha1 to md5 you are losing input range (md5 gives you 128 bit output, but sha1 is 160 bits long). This is rehashing a shortened excerpt, which means the possible output set is never bigger than that of md5().
If you don't hash your passwords tens of thousands of times, you don't know what you are doing.
This is computationally expensive; that is the point. For the legitimate purpose of authenticating a user who has the correct password, the load is negligible. But for a cracker who is trying to test a huge list of passwords in an offline attack, the cost is prohibitive.
Using thousands of iterations of a hash function is a well-established and widely used technique for "key strengthening." It is incorporated in standards for key derivation, and used in algorithms like bcrypt for password protection.
Use bcrypt or PBKDF2, which will require you to use salt and iterations. Don't try to make up your own method using a few broken hashes.
A bit. If the goal is to actually get the original password, it becomes an impossible task. However, usually it is not, and if you really use md4 for the outermost hash, well.. http://en.wikipedia.org/wiki/MD4#Security
There are many other ways to improve security, the most basic of which is to use some kind of random salt that is not stored along with the password.

Categories