Basic secure user password storage workflow - security

Given a raw password
create an unique salt
append it to the raw password
brcypt / SHA512 this combination using disposable secret key that changes over time
stores the encrypted password and salt in the user table
To verify identity
append the salt to the raw password
bcrypt / SHA512 the combination verify
checks the hashed against the db hashed value
In the verify part, what if the current secret key is no longer the same?
Should I always keep a list of old key and iterate them through to verify that that old password is generated with one of the old keys? If verifier returns true, I will update the new encrypted password.
Also, how can I be sure the salt is unique per-password-per-user?
Is this all I need to do?
Any thing missing? Thanks.

Making sure the salt is unique is easy - you could just hash together the username and the time when the password was last changed.
As for encryption, that's only necessary if for some reason you want to store the user's password, not only be able to verify it. It's more common and more secure to only store a hash of the password and salt. No secret key is necessary and even if an attacker compromises the database, they will have troubling recovering passwords. The only downside is that you can't tell users their passwords, you can only reset them.

Related

I don't understand very good the benefits of the salt and hashed password in the client side

I have readed this article:
https://crackstation.net/hashing-security.htm
It is said that in a web application, always it is needed to hash the password in the server to ensure that the hash is correct. But if the client hash the password and sends to the server, the server what to do is hash the password, so how can the server hash the password if what it receives from the client is the hashed password?
The other doubt that I have is the basic steps that it is needed to do:
Retrieve the user's salt and hash from the database.
Prepend the salt to the given password and hash it using the same hash function.
Compare the hash of the given password with the hash from the database. If they match, the password is correct. Otherwise, the password is incorrect.
Well, the server get the password from the client, use the salt with the password from the client, hashes it and compare with the hashed password from the database. Well, how the salt is always the same for this user and it get from the database, if a middle man get the password, can use this password and authenticate in the database, because the server will use the salt and get the same hashed password. So no matter if it is the real user or the middle man, the server allow the access.
Another option is if the server receive the hashed password, it just needs to get the hash from the database, so it avoids to hash, saving resources. Then the client instead of send the password, send the hashed password and the server compare this hashed password from the client with the hash of the database. here, a middle man can get the hashed password too and use it to authenticate. At the end, is the same that if the user send the password.
I don't see the benefit to salt and hash the password, because if a middle man attack the connection, he can authenticate in the database. So I think that the important it is to ensure that the connection is safe, and then is the same to send the password in plain text, because the connection is secure. But perhaps I don't understand something because I know that salt and hash the password it is a common practice.
The only real benefit that I see to hash the password if one attacker get access to the database, because he can not get the password from the hashed password, but if a attacker access to the database, he can get access to all the information, so I guess the less important data is the password.
For that reason I am wondering, Is it not enough with a secure connection? because if an attacker can access to the connection, then he can access to the password and can authenticate in the server. If the attacker can not get access to the connection, then why to hash the password in the server? Is waste resources to hash the password because is a hard process.
Thanks.
Hash algorithms are asymetric, which means that you can generate the hash but going from a hash to the login credentials is much harder.
Keeping the password in an unclear form in the database prevents bad-intended people who can access it to get the clear password and authenticate as the user.
Moreover, it's not by accessing the hashed password record in the database that would allow an attacker to steal the account but by accessing the server source code to determine how the password is generated and then be able to regenerate it.
Considering that firebug for example allows you to access the client source code, you don't want to perform the password generation on the client side.
PS : If you implement SSL and HTTPS, then the packets of your request are encrypted.
We need salts. When you try to login, you hash your password client-side and send the hash to the server. They compare your hash to their hash (they also still have your password in plaintext).
What if an attacker captures your hash in transit? A good hash algorithm won't let them go from the hash back to the password, but hackers can use rainbow tables... They can try tons of passwords until they find a password with the same hash.
To stop this from happening - from the attacker from finding your password - we use a random salt. We add some random stuff onto your password before we hash it so that the hash isn't the same as the hash for your password. We send the new hash along to the server with the salt in plaintext. The server adds the salt to their copy of your password and they hash it. If the hash matches what you sent them, you login.
But since the salt is always changing, an attacker will have a hard time cracking your password.

Reset password in PBKDF2

I store some data which is encrypted, and the key is generated based on the user's password (after hashing and salting) using PBKDF2.
I can implement password change requests simply by decrypting the data with the old password, then reencrypting the data with the new password.
However, how do I go about implementing password reset, when the user forgets their password? Should I be storing things differently to support this use case? If so, how?
I can implement password change requests simply by decrypting the data
with the old password, then reencrypting the data with the new
password.
However, how do I go about implementing password reset, when the user
forgets their password? Should I be storing things differently to
support this use case? If so, how?
Typically you use a Content Encryption Key or CEK. The CEK is a random key, and you use it to key you block cipher and MAC that protects the file. Each file gets its own CEK and other crypto parameters, like and IV or nonce.
Then you use a Key Encryption Key or KEK. In you case, the KEK would be the output of you PBKDF. The KEK encrypts the CEK.
For recovery, you create a recovery key. Then you encrypt the CEK again under the recovery key, and move the encrypted CEK somewhere safe.
When it comes time to change passwords, you just re-encrypt the CEK under the new PBKDF derivation. No need to mess with the recovery key since its safe somewhere else. (Or as safe as it can be with governments issuing NSLs with no oversight).

Understanding Password + Salting

I'm having trouble understanding the benefits of storing user data in a database table using salting. The process I have set up is as follows:
User creates account with username/password
A random salt is generated.
Username stored in database, password encrypted and stored, salt stored along side password.
Now when a user attempts a login, they provide their username/password and:
Finds salt in database based on username.
Encrypts cleartext password provided using salt from database.
Compares the stored password and user provided password.
This is all fine and dandy, but doesn't a hacker merely have to guess the username and password combo? As long as they can determine a username, they can retrieve the salt. Using a brute force attack they would only need to determine the correct username/password combo. The salt would be retrieved with just the username and added to the provided password in order to compare to the stored password, so whats the point of using the salt anyways? Its not like the hacker has to guess the salt value. The password they provide is automatically encrypted with the salt from the database so as long as they know the username, its just a matter of guessing the password in cleartext.
The point of the salt is to force the hacker to attack each username one at a time rather than allowing him to attack all of them at once. Because each username has a different salt, the very same password would be stored differently for it. This defeats a rainbow table attack.

Identifying frauds while salting passwords

Im in the works of updating the login process of a site.
Currently, passwords are stored as md5(password), and i'd like to add a salt,
but the unsalted password is being used to identify possible frauds since they
usually uses the same password for new accounts.
20% of the traffic is from mobile devices, which don't necessarily have the same ip.
Any idea how to identify these possible frauds?
You can still add a salt, but you have to do the comparison to the existing passwords while you still have the plaintext password, i.e. you'll have to loop through the passwords table looking for duplicates (by hashing the other account's salt with the new password) at the time the account is created rather than afterwards.
I would say salting passwords is definitely a major benefit over keeping them unsalted for fraud prevention purposes. However, please use a cryptographically secure slow hashing algorithm, such as bcrypt, scrypt or pbkdf2 - not salted MD5.
But you could have your cake and eat it, why not have another table that contains previous passwords that have been used in fraud attempts? These would be hashed, but not salted and would not have any account association stored.
If a user that uses one of these passwords turns out to be non-fraudulent, you could give them a notification to change their password to something else after you have investigated.
Here's how I imagine it would work for adding new passwords to the fraudulent password list after an account is determined to be used for fraud.
Account is marked as fraudulent.
When this user next attempts to log in, and their hashed, salted password matches the hashed, salted value stored in their account record, the unsalted hashed password taken from their user input is stored in the fraudulent password list.
As the fraudulent password list could reduce the security of the accounts of upstanding users because they are stored in here unsalted, you should make "good" users change their passwords upon login if it matches any in the fraudulent password list.

How can I change the AES-256 key after encryption?

I've a website that users submit their personal data to, and I'm thinking of encrypting these data using AES-256 and their password is used as a key for that encryption and then I store the encrypted data in a MySQL database...
Now if the user changes his/her password, how would I change the key of the encrypted data?
Should I gather all the data from the database, decrypt their data with the old key, and then encrypting it again with a new key?
You don't need to re-encrypt all of the user's data when they change their password.
Generate a secret key to encrypt a user's data; call this the "content encryption key." Derive a key from the user's password; call this the "key encryption key." Encrypt the "content encryption key" using the "key encryption key." Store the encrypted key along with the salt and the number of iterations used for key derivation.
If they change their password, decrypt the content encryption key with the old password, and re-encrypt it with a key derived from the new password. You should choose a new salt for the new password, and make sure you store it along with the new encrypted key.
Because the content encryption key is randomly chosen from a huge space, you can safely use ECB as the cipher mode when encrypting it.
Don't simply hash the password, even if you use salt or even if you use an as-yet-unbroken algorithm. You need to repeat the hashing operation thousands of times. There are libraries for doing this (correctly) on most platforms. Use a key derivation algorithm (PBKDF2, from PKCS #5) to create a secret key from a password.
This concept follows the draft for password-based S/MIME encryption.
One possibility to consider decouples the key used to encrypt the data from the key used to gain access to the data. Done carefully, this allows the user to change their password as often as they desire, while you only change one record in the database. Separately, you can schedule changes to the key(s) encrypting their data when it is convenient for you.
How does it work?
You encrypt the data D for user U with a randomly generated key, KU,D.
You encrypt the key KU,D with a separate key K1U,K generated from a random salt, S1U (which you keep a record of) and the user's password P1U (which you may or may not keep track of). The encrypted key is E1U.
You store S1U and K1U,K ready for when the user wants to access their data.
When user U wants to access their data, they provide you with their password, P1U, and you look up S1U and regenerate K1U,K from that data, and use that to decrypt E1U, giving you KU,D once more, with which you decrypt their actual data.
You ensure you can detect when the password given is correct so you don't spew forth binary gibberish if the users types the wrong password.
The advantage of this level of indirection comes when the user wants to change their password. If you don't use some technique analogous to this, you will have to get and validate the old password and the new password, decrypt all the data with the old password, and re-encrypt it all with the new password.
With the level of indirection, you still prompt the user for their old password (P1U) and their new password (P2U) and validate them, but you only have to decrypt E1U and then re-encrypt it with a new key K2U,K generated from a new salt S2U and the new password P2U. You do not have to touch the encrypted data at all.
With the level of indirection, the system S can also keep a second encrypted copy of the data key KU,D, encrypted with the system's password. If it becomes necessary or desirable to change the key used for encrypting the data, the system can use its encrypted copy of the key to do so. It can keep a record of which key was last recorded by the user in their key, so when the user returns to look at the data, it can arrange to to change the stored key K2U,D because at that time, it has their password (the rest of the time, it does not).
This is a mild variation on some of the ideas in "Cryptography in the Database: The Last Line of Defense" by Kevin Kenan. The KnU,K keys are examples of a KEK, a Key-Encrypting Key. You could also read about key families in the book, which would help with the management of encrypted data.
First, you generally shouldn't use the password as an AES key. Maybe something like a cryptographic hash (not MD5) of the password + a salt (you would store the salt but not the hash in this case).
One thing you could do is encrypt each user's files with a random key, then encrypt that key with the hashed+salted password. If the user changes passwords, you only have to re-encrypt the key.
That’s silly.
AES uses a 256-bit key, so when you say that you will be using their password for the key, it won’t be nearly as long as the key size requirement.

Resources