I have an express application that generates a hash using bcrypt and I have a login page that retrieves that hash and compares it with the entered password.
Problem:
I have uploaded my code and my database and now I can't login. If I generate my password on my server then I can login but I cannot use my local machine hashes. If I bring the hash generated on my server to my local machine then I can't login in my local environment. I have also generated hash online and replaced my hash password and again I can't login. It seems the password must be generated on the same machine otherwise it won't work
Can someone explain what's happening? Also, how can I fix this?
I am using bcrypt-nodejs module for password hash . But when want to forget password feature , how to get actual password ? My actuall password already encrypt
by salt and bcrypt-nodejs.
That's one of the major security features of bcrypt is that you can't get the original password after it has been hashed. You can only compare hashed values. So for a "Forgot password" feature, the user will have to set a new password.
Given that you really have to perform your password hashing on the client side, how can you implement server-side salting?
The first solution that I can think of is to ask for the user's salt from the server's users table before you perform the hash. But that means you're confirming that the user "exists" since you give him the valid salt of the user.
I've also thought that instead of storing the salt in the user's table, you can make the salt something that is available to the user, for example, a variation of his username. But consistency problems might arise because the server and the client needs to remember how exactly the salt is gotten from the provided user data.
What is the best way to do this?
I'm no expert with regards to the topic but how about using something like a one-time salt along with the solutions you mentioned.
Meaning, you provide the client a salting function that generates a salt based on a random seed for a short time frame. The seed itself is dynamic and changes after some time and must be the same between the server and client. After all, the salt need not be secret.
On the client side generate the salt using the username (or whatever user data is available) assuming it is unique. Then you generate the hash on the concatenated password and salt and send it on the server.
On the server side, you calculate the salt using the same salting function in the client with the username as the input. You then generate the hash just the same and determine if the two values match. You just have to make sure the time window is wide enough to allow successful authentication.
Hashing client-side is useful if you don't have HTTPS for logins, but it can have some disadvantages such as revealing your hashing and/or salting methods. That being said, if they have access to your password hash database, they probably already have access to that information.
In order to do only a server side salt, you will need to rehash the password using the salt and password hash. In this scenario you would store only the username, salt (if not using a username and password hash salt) and second hash.
If as from your example you wish to perform the salting on both client and server, I would suggest using a combination of username and the initial password hash to salt. The salt won't be unknown by the client as anyone could check your salting method and even apply it to a password cracker, but it will avoid them using a rainbow table to crack same password users.
Don't use the username by itself as a salt. If its a common username (eg. admin), then there is probably a table out there already with this salt.
The problem with using nyde1319's answer (sorry didn't have rights to comment on the answer) is that you will need to have an unencrypted version of the password in your database to perform the password+salt hash. Defeating the purpose of the hash. If it was done using a hashed version of the password, you'd have to store the first hash and they could just crack that hash, defeating the purpose of the salt.
I have a system where users can signup by Facebook or by a regular form. If user signup by Facebook, my system generates a random password, just to allow user to log-in without Facebook if he wants. If user signup using regular form, he can type any password he wants. In both ways, password are encoded into a MD5 hash, but without salting. It's is insecure, I know, this is the reason i'm here.
I don't know the best strategy to convert the passwords into secure ones... First i'm thinking to keep the MD5 insecure password, and when user log-in, i can match the password without salt, salt-it, and then update the database. But it doesn't solve my problem, because system will still accept the insecure password. Besides that, user can still log-in using facebook, witch do not allow me to update their password (since he didn't used it).
So, have anybody an idea to minimize the impact instead of just force everyone to update the passwords?
Thanks!
So, I've done the following actions to solve my problem.
Created a column "LastPasswordChange" in users table.
When user changes password, the field is updated with current date, ALSO, an e-mail is sent to user to inform that password was changed, with a link to revert it in case of this is wrong (due to a possible hack).
The e-mail allow user to log in and set a new password without knowing the last used.
When user log-in using the current password, it looks to the LastPasswordChange field, and if it is null, it allow the login without using the salt.
In any way he/she logs in (Facebook or Login/pass), system looks to the LastPasswordChange field, and if it is null, system requires user to change the current password to a different one (not match the old one without salt).
That's it.
What is the best way to handle user account management in a system, without having your employees who have access to a database, to have access to the accounts.
Examples:
Storing username/password in the database. This is a bad idea because anyone that has access to a database can see the username and password. And hence use it.
Storing username/password hash. This is a better method, but the account can be accessed by replacing the password hash in the database with the hash of another account that you know the auth info for. Then after access is granted reverting it back in the database.
How does windows/*nix handle this?
This is a better method, but the account can be accessed by replacing the password hash in the database with the hash of another account that you know the auth info for.
There's really no way around this. Anyone who as write access to the password file has complete control of the computer.
This was a common issue in UNIX many years ago, and was resolved by separating the user identity components (username, UID, shell, full name, etc.) from the authentication components (password hash, password hash salt). The identity components can be globally readable (and in fact must be, if UIDs are to be mapped to usernames), but the authentication components must be kept inaccessible to users. To authenticate a user, have a trusted system which will accept a username and password, and will return a simple result of "authenticated" or "not authenticated". This system should be the only application with access to the authentication database, and should wait for a random amount of time (perhaps between 0.1 and 3 seconds) before replying to help avoid timing attacks.
I'd go with 2 but use some salt. Some pseudocode:
SetPassword(user, password)
salt = RandomString()
hash = Hashfunction(salt+password)
StoreInDatabase(user, salt, hash)
CheckPassword(user, password)
(salt, hash) = GetFromDatabase(user)
if Hashfunction(salt+password) == hash
return "Success"
else
return "Login Failed"
It is important to use a well known hash function (such as MD5 or SHA-1), implemented in a library. Don't roll your own or try implementing it from a book its just not worth the risk of getting it wrong.
#Brian R. Bondy: The reason you use salt is to make dictionary attaks harder, the attacker can't hash a dictionary and try against all the passwords, instead she have to take the salt + the dictionary and hash it, which makes the storage requierments expode. If you have a dictionary of the 1000 most commaon passwords and hash them you need something like 16 kB but if you add two random letters you get 62*62*16 kB ≈ 62 Mb.
Else you could use some kind of One-time passwords I have heard good things about OTPW but havent used it.
Jeff Atwood has some good posts concerning hashing, if you decide to go that route:
Rainbow Hash Cracking
You're Probably Storing Passwords Incorrectly
You could use openID and save no confidential user passwords at all. Who said it is for websites only?
A very bad idea indeed. If the database is compromised, all accounts are compromised.
Good way to go. If your hash algorithm includes the username, replacing the password hash with another one will not work.
Unix stores hashes in a a text file /etc/shadow, which is accessible only to privileged users. Passwords are encrypted with a salt.
You could store the salt for the hashed password in another table, of course each user would have their own salt. You could then limit access to that table.
The usual approach is to use option two with email:
Store user name, password hash and email address into the database.
Users can either input their password or reset it, in the latter case a random password is generated, a new hash is created for the user and the password is sent to him via email.
Edit: If the database is compromised then you can only guarantee no sensible information can be accessed, you can no longer ensure the security of your application.
Hash the username and the password together. That way, if two users have the same password, the hashes will still be different.
This is a bit of a non problem for a lot of applications because gaining access to the database is probably the most common goal of any attacker. So if they already have access to the database why would they still want to login to the application ? :)
If the 'system' is a public website RPX can provide you with a login/user account services for the most common providers, like OpenId, Facebook, Google, etc.
Now, given the way you formulate your question I guess the 'system' you're talking about is more likely an internal windows/linux based enterprise app. Nevertheless; for those googling around for login/user account providers (like I did before a came across RPX), this could be a good fit :)