Best practice on generating reset password tokens - passwords

Any best practice on how a reset password token should be constructed? I'm thinking:
random 17 characters [a-zA-Z0-9] + a globally unique id + random 17 characters [a-zA-Z0-9].
Is there a better solution, or an industry standard on reset password tokens?

There are some important points to consider.
The code should be really random (read from MCRYPT_DEV_URANDOM), and should not be derrived from other user related information.
Ideally the code is base62 encoded (A-Z a-z 0-9) to avoid problems with the Url.
Store only a hash of the token in the database, otherwise an attacker with read access to the database can reset any account.
This leads to the problem that you have to find the hash of the token in the database, after the user clicked the link. There are two possible ways to store the token:
You hash the token with a hash algorithm like SHA512 without a salt. This is secure if the token is very strong (minimum length 20 with 0-9 a-z A-Z). Theoretically you have to check whether such a hash already exists before you enter it in the database, in practise this is negligible. I implemented a password-reset class that can handle such tokens.
You hash the token with BCrypt and salt. This allows for shorter tokens, but you cannot search for the hashed token in the database. Instead you have to include a row-id in the link to find the token.

Related

JWT, Using a dynamic secret key stored in DB

I need some advice about future pitfalls and problems if I go forward with below approach.
I am using JWT and I need to expire all previous tokens of a user when he/she changes his/her password.
The approach I took to make a unique secret key for each user is concatenation my secret key and user password (config.jwtSecretKey + user.password) to generate a dynamic secret key.
Once the user changes his/her password the secret key will change and hence all previous tokens will be invalid.
Things are working fine but to validate each token I need a DB call to get the password.
Please suggest how can I improve this or what is the right way to do the same.
Your approach is quite good as it's to KISSy
The database query can be reduced by using some in-memory cache of your dynamic secret key.
Also, you can change the dynamic key from password hash to some random hash to reduce conflicts. It will reduce a lot of security threats.

Convert passwords with sha256 to sha256 + salt

I have big database with user and passwords in sha256 hash. Now I write new version and I want to use sha256+salt. Is there a way to convert same passwords with sha256 to sha256+salt and have no trouble with login?
Surely it is a good idea to make your password hashes more safe, but using a salted SHA-256 is the wrong way to go.
Best practise is to use a password hash function with a cost factor, which allows to control the necessary time to calculate a hash. Good algorithms are BCrypt, SCrypt, Argon2 and PBKDF2. In another answer I tried to explain how the switch to a new algorithm could be done.
The problem with the fast hashes like SHA-256 is the unbelievable speed of GPUs, one can brute-force about 3 Giga SHA-256 per second with affordable hardware.
The way to salt and hash a password is to take the plaintext password, add the salt to it and THEN hash it. When you have an existing password database already sha256-hashed you don't have the plaintext passwords, and you can't easily get them back in plaintext once hashed (which is a good thing).
What you could do instead would be to take the passwords in their current form, sha256 hashed, add the salt and then hash them a second time - or better: many times, with better hashing algorithms.
The function to verify the password would then repeat those steps to check that the password is correct. Assuming the second hash is just sha256-hashing once to make the example clearer, though it's not sufficiently secure:
step1 = sha256(plaintext_password)
password = sha256(step1 + salt)
If you really want to avoid working on top of your existing hash you could create a new table of users where you process passwords in the new way from the beginning, and then gradually migrate user's passwords over to the new table as they log in with their plaintext passwords, and remove them from the old table.
A third solution could be to deactivate all the old accounts and require them to change their passwords before they can sign in again, via fx. e-mailing them a link to change their passwords.
Makes sense?
That said you will get more qualified answers at https://security.stackexchange.com . For instance I just found this question on why salt->sha256 hashing once is insufficiently secure, and another one here on how to process passwords for more secure storage.

Store one big Hash instead of User/Pass in DB

Normally a password is stored with a one-way algorithm, so that it makes hard to discover the plain text from it.
But I've been thinking: What if I store a SHA512 of both username and password melted together (A+B=SHA512), instead of the username and the password hash separately.
Is this method secure?
EDIT: In my opinion the Username 'salt' the password, so there will be no equal hash two times...
(1) You should be using something like bcrypt, scrypt, or pbkdf2 instead of something like SHAwhatever for password processing. Google this.
(2) How would you deal with forgotten password scenario?
(3) See my blog, particularly the section on "A simple example: protecting email address": https://littlemaninmyhead.wordpress.com/2015/09/08/a-retrospective-on-ashely-madison-and-the-value-of-threat-modeling/
Sure that would work. But would you ever want to retrieve a list of user names?
In the authentication implementations I have written, I use the username as part of the salt. That combined with a sitewide salt plus a bit of constant salt ends up creating around 120 bits of salt per username.

VB.Net Password Hashing practices

I'm trying to secure a website that is being moved to a public server soon. I've just finished adding the password hashing functions to all of my login scripts. I'm using FormsAuthentication.HashPasswordForStoringInConfigFile(pw, method) to do so. I have a question about the process I'm using and whether or not it's secure for a web server:
Password is sent in plain text over HTTPS to the server
The server looks in the Users table to find the user's Salt (several random characters) and their hashed and salted stored password
The plain text password is appended with the Salt
The new string is hashed using the above function
The newly hashed version is compared to the stored version
If equal, login is allowed
If not equal, the login attempt is logged in Session variables, up to 3 times before locking out the user's machine from accessing the login page until an admin verifies IP address and unlocks.
Does this look about right? I just don't see how the salt is effective in this method... Anyway, all I've done is add a salt and hash. Is this considered Encryption? Or am I missing a step? I remember reading that hashing algorithms like SHA1 and MD5 are not encyption algorithms, so what else needs to be done?
That is correct. The salt is used to prevent rainbow table attacks where a dictionary of common works hashed with MD5 is used to try to gain entry. Using the salt ensures that even if they had an MD5 hash of the word, it wouldn't work because they don't know the salt.
The MD5 algorithm is a 1 way hash algorithm, and not an encryption value. The difference is, once you've hashed the value, there is no way to get back to the original value. Encryption allows you to decrypt the data and get back the original value. So you are correct, they are not the same, and your passwords are not encrypted, they are hashed. This means that if someone forgets their password, you cannot send it to them. You have to provide a way for them to reset their password instead. This also means that anyone with access to the database would not have access to raw passwords. Which is good because a lot of people use the same password everywhere, and if you had access to a large list of usernames and passwords, someone could decide to start trying to log into bank / credit card websites.
What you are doing is a recommended practice.
You shouldn't be storing the retry count in the session - an attacker could simply discard their session cookie after each attempt, allowing them to retry as many times as they wish. Instead, store it against the user record.

Salted hashes and password histories

Wondering whether it matters if a salt is unique for a single given user each time the password is changed, or whether it's not a big deal to reuse the same salt each time.
I currently generate a new random string as the salt each time a given user updates the password. This way each time the user has a new password their is also a salt change. It's easy to do, so why not.
Well... here's why. I need to store the previous X passwords to ensure a password is not reused. In the old days (the last time I wrote code for this), I could just store previous MD5 hashes, and compare new ones to that list. Well, now that I am using salted hashes where the salt is unique each time, those comparisons are no longer possible as the previous salts are no longer known.
To make that system work, I have two choices: store a history of the salts in addition to the final hashes, or reuse the same salt for any one given user with each password update. Either of these would allow me to build values that could be compared to a history.
The latter is less work, but does it lose any strength? From a practical standpoint, I don't see that it does. Thought I'd get a second opinion here. Thanks.
To keep the question "answerable" -- would reusing the same salt for any one user have an acceptably minimal reduction of protection in order to maintain a searchable password history (to prevent pswd recycling)?
Reusing the same salt means that if a user is explicitly targeted by a hacker, they could produce a "password to hash" dictionary using "the user's salt" - so that even if the user changes their password, the hacker will still immediately know the new password without any extra work.
I'd use a different salt each time.
As for storing the MD5 hash plus salt - presumably you're already storing the salt + hash, in order to validate the user's current password. Why can't you just keep that exact same information for historical checks? That way you can use one piece of code to do the password checking, instead of separating out the current and historical paths. They're doing the same thing, so it makes sense for them to use the same code.
EDIT: To explain what I mean, consider a 4 character salt, prepended to the password... and for the sake of argument, imagine that someone only uses A-Z, a-z and 0-9 in their password (and the salt).
If you don't know the salt ahead of time (when preparing a dictionary attack) then in order to prepare a dictionary for all 8 character "human" passwords, you need to hash 62^12 concatenated passwords. If, however, you always know what the first 4 characters of the concatenated password will be (because you know the salt ahead of time) then you can get away with only hashing 62^8 values - all those beginning with the salt. It renders the salt useless against that particular attack.
This only works with a targeted user of course - and only if the attacker can get at the hash list both before and after the password change. It basically makes changing the password less effective as a security measure.
Another reason for using salt in password hashes is to hide the fact that two users use the same password (not unusual). With different hashes an attacker won't see that.
Firstly, stop using MD5 (if you are using it), and use SHA-2, MD5, SHA-0, and SHA-1, are all dead hashes.
-- Edit:
I now agree with Jon Skeet, and suggest you consider generating a new salt with each password change. It covers a small case where the attacker may get the salt+hash, then not be able to gain access again, but will still allow him (with some guessing of how you combine them), to calculate what the hashes could be for all future passwords. It's very small, and is not so important, because the password sizes will need to be significantly small (say, 8 chars) for even calculating them all offline to be practical. Yet it exists.
Secondly, to consider whether or not it matters, we need to think about the purpose of salts. It is to prevent offline attacks against someone who has a complete listing of only the passwords.
On this basis, if the salt is equally "difficult" to obtain before and after password changes, I see no use a new salt (it's just as at-risk as it was before). It adds additional complexity, and in implementing complexity is where most security problems occur.
I might be being incredibly dim here, but, where would you store the salt that would be inaccessable to someone with enough access to get the hashed password.