Is storing a password in the DB using MySQL's password function just as bad as this?
http://money.cnn.com/2012/06/06/technology/linkedin-password-hack/?source=linkedin
The problem with SHA-1 is that it translates the same text the same way each time. So if your password is "password" and your friend's password is also "password," they will be hashed exactly the same way. That makes reversing the process to uncover the original password significantly easier.
I know it says SHA-1, but obviously any unsalted one way hash would have the same issue.
Is storing a password in the DB using MySQL's password function just as bad as this?
Yes.
Generally speaking you want to use a method that includes a salt, preferably unique for each user, and is slow to run to prevent brute force cracking. Bcrypt is the currently recommended way to go when storing passwords because it is intentionally (relatively) slow to create.
MySQL documentation says that you shouldn't be using the PASSWORD() function in your own application:
The PASSWORD() function is used by the authentication system in MySQL
Server; you should not use it in your own applications.
Internally, MySQL's PASSWORD() function utilizes SHA1(2), that's SHA1 twice. However, it doesn't utilize a salt. So, yes, it's still vulnerable to rainbow table attacks.
Related
I've seen a lot of topics about hashing and salting a password and then comparing them with the hash and salt in a MySQL database, however none of them really helped.
They were either really 'vague' or not in the right coding language.
I am coding in Visual Basic.
So, I'm using a Forum Software called 'MyBB' and it encrypts the user's password to a MD5 Hash and generates a salt alongside it.
I have successfully connected to the MySQL database and I'm able to login with my application using the Username, however because I haven't yet hashed the password and salted it then compared the two.. I'm unable to login using my original password - instead I have to use the MD5 hahsed password from the database.
My question is:
How do you Hash the password then salt it and then compare it the two so that I'm able to login using my original password without having to use the MD5 hash from the database?
Any help would be appreciated.
I have searched and read numerous amounts of topics, however none of them provided how to do it. It briefly mentioned you need to hash it and salt the password then compare the two, however it didn't provide any code or steps of how to do it. Also there is little topics on doing this in Visual basic. Most of them are for php and c# which is not helpful when you don't primarily code in those languages.
Hashing and salting fell out of style in the 1990s, and MD5 is such a terrible choice for hashing in general, and passwords in particular, that you should never use it.
The recommended way is to use password_hash to properly hash passwords, and password_verify to verify them.
Both of these use Bcrypt by default, a password-specific hash that's very hard to crack.
You can use Bcrypt in both PHP and other languages, it's a well-defined standard that's supported by .Net applications just the same. MD5, even "salted", is completely inadequate and needs to be replaced immediately.
I'd strongly suggest you switch over to Bcrypt-based passwords as soon as you can and migrate all your users over from MD5 to Bcrypt. Each time they log in you can update the password field if you know the MD5 hash matches.
For an example of how utterly useless MD5 is, search for 73868cb1848a216984dca1b6b0ee37bc.
I am creating a database and I need to store user passwords. I am already using bcrypt to hash the passwords on the client side, but I have read that only hashing on the client side makes the hash essentially equivalent to a password as far as the database is concerned. I'd like to hash the passwords (which are now hashes) again before they are stored in the database. Do I have to use a method native to MySQL like SHA2(pwd), or is there a way to use bcrypt on the server?
Bcyrpt is a good call here, but you should be doing the hashing on the server end, not the client. The client can't know all the information it needs to produce a hash you can verify is correct, only the server has that information.
What you need to do is pass through the password securely, such as over HTTPS, and hash it there in your application layer. MySQL alone does not have the functions necessary to do proper password hashing. SHA2 is completely inadequate, it's a high-speed hash by design which makes it immediately unsuitable. Password hashing algorithms are deliberately slow to make brute-forcing passwords painfully expensive.
What is the most secure way to encrypt user passwords for phpBB or MyBB forum registrations? I don't want anyone to be able to access the user passwords, not even those who administrate the MySQL database, and also if someone manages to hack the database to not be able to view them. I want only the users who register to know their passwords.
I completely agree with the response Federico Razzoli, except for one thing. Indeed, hashing must be performed upstream, in any case not at the database level (so your question is probably off topic).
However simply using a hash function is not sufficient in terms of security. You remain vulnerable to dictionary attacks, rainbow table attacks, and some attacks by frequency analysis. It is essential to at least use a cryptographic salt.
However, the best is to use a key derivation function designed to store passwords. I suggest you to look at PBKDF2 (hash_pbkdf2 with PHP), bcrypt (password_hash with PHP, which by default uses a judicious algorithm, bcrypt currently) or scrypt.
Finally, your question suggests that you use phpBB, this forum engine should normally deal alone with the secure storage of passwords.
You can use SHA512.
I see that you used the "mysql" tag. Please, don't use the SHA2() SQL function, or any other SQL hash function. If you do so, the plain strings will be sent across the net, and probably written in some logs.
Use the PHP hash() function instead, and specify 'sha256' as first parameter.
In MySQL documentation for PASSWORD function:
The PASSWORD() function is used by the authentication system in MySQL
Server; you should not use it in your own applications. For that
purpose, consider MD5() or SHA1() instead.
Why we shouldn't use this function in our application?
A few reasons I can think of
It's a fast hash (SHA1 I believe) which isn't a good property for password hashes.
They might change what hash it uses in a future version of MySQL, breaking your application. They've already done this once, hence the OLD_PASSWORD() function.
It doesn't naturally use a salt (although you could use a salt with it if you wanted to by appending it to the password before calling the PASSWORD function)
It's non-standard SQL, so if you ever need to port your app to another platform you'll need to come up with a replacement
I'm looking to migrate a table of user data to my shiny new MongoDB rig. Having trouble wrapping my head around how to handle a column of passwords. I'm using MySQL's PASSWORD() function to store the passwords. When the thing was constructed I didn't see any reason to ever need to reverse the encryption, so I didn't see any harm in using the PASSWORD() function. But now I can't transfer the passwords as is, because (as far as I know) I can't use PASSWORD() the same way in MongoDB to check the validity of the password.
Any ideas?
You have several options:
Option 1: Lazy migration.
Keep both your MySQL and MongoDB servers online and connected. When a user attempts to log in, check the password against MongoDB. If it fails (ie, a password was never set), then check it against MySQL. If it succeeds, then hash the password and store it in the MongoDB document.
Downsides: Your MySQL server has to stay online forever (or at least until all your users migrate).
Upsides: You can easily replace the MySQL password format with your own format (ie, bcrypt hashes or whatnot). You don't have to have any knowledge of how MySQL is hashing passwords internally.
Option 2: Figure out how the MySQL password() function works, and replicate it clientside.
According to Simulating MySql's password() encryption using .NET or MS SQL the algorithm MySQL versions 4.1 and greater use for PASSWORD() is "*" + sha1(sha1("password")), more or less. If you're running an older version, you'll need to find out what the hashing algorithm is, and use it instead. You can just take your password, double SHA1-hash it, prepend an asterisk, and check to see if that value matches what's in the DB.
Downsides: The exact algorithm depends on the version of MySQL you're running, so you might have to do a bit of digging depending on your MySQL version. You're still stuck using the MySQL password format in your MongoDB documents (though you could do a lazy upgrade, with a procedure similar to what was described in option 1).
Upsides: You can do the migration once and then take your MySQL server offline.