After reading some posts and articles online, it seems that most, if not all, people suggest using some sort of hashing algorithm for keeping a user's password safe, since you cannot unhash it, which is good, but that's where I begin to have a problem with my situation.
Right now I am in the early stages of modifying the way we secure our users' passwords. We currently store the hashed passwords in our MySQL DB using Sha512. With my current understanding, although hashes may be secure in the sense that they cannot be reverse (or at least not so easily), it is also insecure in that there are possible collisions, since a hash has a fixed length no matter the size of the original input, which limits the number of possible hashes, causing a possible Pidgeon Hole problem.
Now comes another part that I have a problem with, especially for my case.
I am trying add some features to our users' password where the user cannot enter a new password if it is too similar to, say, their last three passwords. Ex: if their last password was password1234 and their new one is xxxpasswordxxx, then it would fail. However, from my understanding, it is not possible for me to add this feature since I have no way of unhashing their previous passwords to check if any substring in their old passwords are in their new password. This brings me to the whole encryption/decryption part.
I have been looking at AES 128 using a CBC encryption mode and it seems like a solid choice, since I don't really care much for parallelization in the encrypted portion. Additioanlly, by using an encyption route instead of a hashing route, I can actually do that check to see if their last three passwords are similar to their current one! BUT, there is the whole problem of being able to see the users' plain text password in the first place.
Additionally, I have been trying to think of a way to use unique keys for every single password without storing it in our DB because I feel that is way too insecure. I could just use a static randomly key for ALL passwords, but I am not sure if that is a good idea either, even if I use unique IVs for all the passwords.
So to sum up my situation is this:
I want to be able to prevent the user from entering a password similar to their old one's, in addition to actually improving the security of our password storage. From the knowledge I have at the moment, I can either continue storing the passwords as a hash, but I won't be able to do the similar password check OR I can encrypt the passwords instead, which is something that is frowned upon.
I am clearly not an expert in this and I know for a fact I need to do some more research, but I want to make sure I am starting in the right direction.
Regarding the second paragraph: hash collisions are absolutely NOT a problem. For which attack scenario do you think that is a problem? You should really stop throwing buzzwords around, especially regarding security.
You are partially right that your feature idea would fail. And that is a good think because the idea is bad. Why do you want that "feature" - it will only annoy users and cause people try to circumvent your restrictions using numbers at the end including the month or some other incrementing from version to version.
And encrypting passwords is bad - period.
As soon as you can decrypt them, an attack can as well - end of story.
Personal experience of pretty much the scenario you are describing: The client has a tool where you are forced to change the password every 2 months, I am currently at "password"10. I am doing exactly what everybody is warning about when forcing password changes every X months - simply altering the same password piece by piece. I have a very good password (15+ characters, upper and lower case, numbers, special chars) plus a system for choosing a password for whatever site I am setting an account up for. Forcing me to change my password breaks my "system" because now I can no longer generate the password in my head over and over again because the outcome will not match what the site has forced me to set up after the first two months. If the site would start introducing some password similarity restrictions I would probably start writing them down.
Why not keep using hashing, but require that the user enters his or her old password when changing to a new password, that way you can authenticate the old password to authorize the password change, then compare the plain-text versions of both for similarity before proceeding with the change?
when you keep hashed passwords, you can not check for similar passwords, but you could prevent them from reusing a password they used before. By keeping the old (hopefully salted!) passwords, you can compare hash(new_password + old_salt[i]) with the salted_hash[i] of the old password. If they are the same, the user is reusing an old password.
I totally agree with the others that hash collisions are not a problem. You are planning to use SHA512, that is 512 bits of randomness the attacker has to compete with. The only way you could break that is by using rainbow tables and you protect yourself against them using the salted hashes (i.e. even if the password is the same, the salted hash will result in different hashes; it is not a problem if the attacker gets to know both the salt and the hash, so you can store salt + salted_hash in one location).
For security reasons I'd ditch the "similar password" thing altogether. If the attacker gets a bunch of passwords, changes are that there are a lot of bad passwords in your database. Using heuristics and dictionary attacks he will have a good change to guess your encryption key --> immediately unlocks all passwords of all users.
The only safe way for passwords is if the operator of the system storing them cannot recover them either. Anything else is just the next 0-day bug waiting to be exploited.
currently store the hashed passwords in our MySQL DB using Sha512
SHA-512 is too fast. Any attacker gaining access to your password hashes can very quickly run their password guesses through your hash. You need a slow algorithm so each guess takes them thousands of times longer. But as you need to hash these passwords too, you need to choose a value that won't overload your system, or arguably even worse, test your users' patience. Use either bcrypt (on its own) or PBKDF2 in combination with your SHA-512 (although SHA-1 HMAC is more than enough).
it is also insecure in that there are possible collisions
The collision resistance of SHA-512 is not a problem until you are approaching 2256 users within your system. As there are not even close to that number of people on the planet, I can safely say your system will be fine.
Dilemma of choosing either to hash or encrypt passwords
If you need a reason to go with the former, have a look at the details of the Adobe breach. They were encrypting passwords instead of hashing. TLDR; disaster. If your system is even moderately sized, you don't want anything like this being presented by the media regarding your system. Do things properly - use PBKDF2 or bcrypt - that way you are looking after your users using industry accepted methods and cannot then be criticised for your password storage scheme.
by using an encryption route instead of a hashing route, I can
actually do that check to see if their last three passwords are
similar to their current one
Well since the user will (hopefully) be entering their previous password as an additional authentication check in order to change their password, you could compare their passwords at this point as you will have them both in cleartext. For example
old password != new password
lowercase'd letters in old password != lowercase'd letters in new password
adding up all numbers in new password > adding up all numbers in old password + 2 || adding up all numbers in new password < adding up all numbers in old password - 2
And maybe some other rules you wish to define to prevent password similarity. If these rules are applied between changes from the first password to the second, and then the second password to the third, the user may get used to your rules and may be less likely to make their third password too similar to their first. You could also keep a password history table storing the bcrypt hashes of their previous X passwords (e.g. four), and do an absolute comparison to ensure they are not switching back to one they have previously used. I wouldn't keep more than four just in case any of their previous passwords are weak enough to crack and have been reused on other sites, because any breach on your system could potentially expose them, and also as mentioned checking these will be a slow process. You could however, going forward ensure that the user doesn't choose any password that has been involved in any breach by loading common passwords into a blacklist on your system.
Encryption of passwords is a bad idea, and the security benefit of fuzzy matching on all previous passwords does not outweigh the security risk of having two-way encryption active (in my opinion).
To keep password in a secret manner, you have to hash the password plus a salt.
For each user, you randomly choose a salt, you keep in database the salt for each user.
You store in database hash(password+salt).
When you have to check user's password, just add the salt, hash both and check against database.
If a user change the password, you can change the salt as well.
Aftewhile, you may choose an algorithm or another depending of the security level, SHA2 seems to be a good start.
my friend created his platform using laravel, and he encrypted the users password using laravel Hash. I never worked with laravel. I'm building a simple Android application to list all the users from his website, using PHP and Java, and i would like to decrypt the passwords for the login.
I usually use md5:
$password = md5($_GET['password']);
But he used a different hash. My password appears encrypted like this:
Q5joXS5QBA0xdV2Ed2c80e12ac10766d48ef5d8a916e445064091725156d7776958a3937b5cbe79
Thanks.
Some small research seems to show that they are hashed using Bcrypt. This is different to encrypting because it is one way. So to check if the two passwords match, you will need to encrypt the user input with Bcrypt and then check if the two match.
http://laravel.com/docs/4.2/security - Info on BCrypt.
You could use this to check if your passwords match up.
http://www.bcrypt-generator.com/
EDIT: I would advise against using md5 encryption as it is not very secure and it can "decrypted" by brute force.
Example: http://www.hashkiller.co.uk/md5-decrypter.aspx
We have a typical web-based login system. We want customers to have the ability to generate a "login link" that doesn't ever expire and includes their password.
We want to therefore create a link which includes their password in encrypted form.
NOTE: I know the best way is a lookup table where each link has a unique key... I won't go into why that won't work for us; it won't.
I'm not familiar with public key encryption.. Maybe that's what I need?
Here's what I'm thinking. This still might not be enough, so please let me know:
Definition: user-password refers to the user's password that we want in encrypted form in the link.
We cannot use one encryption key for all user-passwords because it may be possible to derive the encryption key by generating tons of links, so...
Use a standard form of symmetric encryption.
The server has a text file with 1000 complex encryption keys.
When a link is generated (using the PHP script that has that list), one of the 1000 encyption keys is chosen to encrypt their plaintext password (chosen in sequence, not at random to prevent the same from being chosen close to the same time).
Before encrypting the user's password, add something like "s345lm34l5k342342343534432324sdfs" to the start of it, to "salt" it. (Ex: password1 becomes s345lm34l5k342342343534432324sdfspassword1). "Salting" makes it harder to decrypt against dictionary attacks. This salt is kept private. But, of course, there's the risk it can be compromised and it's one salt for all passwords, so...
In addition, there's a second randomly generated salt added to the password. This salt is encrypted with a single strong password. Because both the salt and the password encrypting it is a random pattern of bytes, it makes it harder to determine the salt.
The link maker tool only lets you generate 15 links every 10 minutes, and then locks out the IP.
The link maker tool doesn't not generate links unless the user/password provided to it is actual a functioning user/password combination. That way, if someone is just try to generate links to determine the encryption info, it won't work. Still, theoretically, they could obtain a valid user/password and try to brute force.
Is this secure?
No, because the encrypted password has become the password. Have you tried SSL? SSL should solve your problems, you can just use a plain URL on HTTP level.
I need to synchronize three of them but I have already 18k Asp.Net Members. (Offline synchronization)
So how can I convert default "Password Hashing" of Wordpress and Drupal to Asp.Net Membership's (SHA1 with Salt) ?
I don't know if you can. MD5 and SHA1 are uni-directional algorithms. This is why they are used. They provide security for the user passwords. So you will not be able to revert the hash back to the passwords. Nor can you convert from MD5 to SHA1 directly.
In this scenario I think you are stuck with resetting the Drupal and Wordpress user passwords when you merge. (See edits for alternate solution.)
EDIT: This post had a interesting idea / solution. Write some custom code to generate the SHA1 passwords upon your users first logging in. Collect the SHA1 hashes, and use those during merge. Any users you don't get, force them to do a password reset.
I am very new to web application (ASP.NET). I have source code and database for a complete project.
ASP.NET (Authentication) control is used for login. I don't know the password right now but i can get the login name and password in encrypt format from the database table.
How could I login to the application with only this little information available.
As the control are dynamically created on the pages, it is very hard to debug and find them on runtime.
How could i proceed for login by encrypted password? or is there a way to login by overcoming Authentication control.
The password is probably SHA1 encrypted. Basically what you have to do is SHA1 encrypt the password the user gives you and compare that to the password in your database. Because SHA1 always results to the same thing if the input is the same, you will know that the users given password is correct if both hashes match.
SHA1 encryption is a form of hashing and cannot be reversed.
No, hashed passwords in the database are non-reversible intentionally. This keeps anyone (a hacker?) from reading your database and being able to log in.
As Sam152 said, the passwords are likely SHA1 hashed, so if the passwords are not stored with salt, you can build a rainbow table to find the original password. If they are salted, you need to know the salt to build the rainbow table as well.
You could try implementing custom MembershipProvider by derriving from this class. Then you just override method ValidateUser to meet your requirements. Also remember to modify Web.config.
The point of hashed passwords is that a they can't be used by folks not knowing the decrypted password.
There should be a way to reset the password for users. You could do this and log in based on the reset password.
If you are trying to log in to an active user's account, you may want to consider the implications in doing so without their knowledge (if that is the case). However, if it is just a test user, reseting the password is probably the least cumbersome way. That functionality or procedure should probably be part of web app anyway.
If it's the standard ASP.NET membership stuff, I think it uses a stored proc to check the DB. Just change that and have it return true or whatever.
Adding to the above answers SHA1 encryption output is 40 byte. You should check the length of the encrypted password to get an idea about the kind of encryption..since hash algorithm has predefined no of output bytes, this would help you map with the kind of algorithm and then you should look for possibile salt usage as #MattGWagner said...is the tables in database that stores user information seems like aspnet_users,aspnet_membership, etc? Then this should be the standard authentication provided by windows..Just google and see how it works