MySQL- How to implement server-side password hashing - mysql

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.

Related

How to hash and salt passwords for mysql database

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.

Is it overkill to encrypt an already hashed BCrypt password?

I'm using BCrypt to hash my passwords on the server side. Before I store it in my MySQL database, would it be overkill to encrypt my hashed-BCrypt password or would storing the hash directly in the database suffice?
This website advises to encrypt passwords after hashing them:
As long as an attacker can use a hash to check whether a password
guess is right or wrong, they can run a dictionary or brute-force
attack on the hash. The next step is to add a secret key to the hash
so that only someone who knows the key can use the hash to validate a
password. This can be accomplished two ways. Either the hash can be
encrypted using a cipher like AES, or the secret key can be included
in the hash using a keyed hash algorithm like HMAC.
EDIT: I'm coding in Java. I'm trying to gauge whether the added layer of protection vs. speed performance of read & retrieval of passwords for user logins is worth it or not.
This would indeed increase security, but it is good to know what exactly you gain with encryption.
Encrypting the password-hash can protect weak user passwords from a
dictionary attack, in the special case, where the attacker has
read-access to the database (containing the hashes) but does not have
access to the source code with the key/pepper.
This situation is not so uncommon as one would think, typical scenarios would be SQL-injection, thrown away backups, discarded servers...
To be able to brute-force for passwords one needs the server side key, which was used to encrypt the password-hashes. This means, being able to read the hashes from the database is not enough anymore, one needs additional privileges to read the key from the server. Getting privileges on the server is much more difficult than being able to read the database.
Crackstation is a good site for advice. At the end of my own tutorial about safely storing password I try to explain the details of this password-hash encryption.

How to encrypt user passwords for forum registrations?

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.

MySQL plain-text to hash passwords

I've been working with a clients MySQL database which has users passwords stored in plain text. As I mentioned that this is a huge potential risk we talked about hashing the passwords (not that this is a full solution since it's possible to "de-hash" relatively easily these days) and I've come across a question that I think I might know the answer but I want to be 100% sure.
This client developed a couple desktop applications that require the user to insert their user/password, all in plain-text of course.
So, if we hashed the passwords by updating each password field to its MD5 (for example) hash, would modifying the desktop apps to perform this hash on the password received/input and then compare them (and login) work?
Basically, do the login procedure as it's always been but use hashed passwords instead, being this a transparent and unnoticeable operation to the users?
Yes, this will work and should be transparent to the users.
However, it's not very secure. If someone gets a copy of the login database, they'll get the hashed passwords. And since you're sending hashed passwords over the wire, that's all they need to know -- they don't need to unhash it.
It's better to send the plaintext password over the wire, and do the hashing in the server application or database query, e.g.
SELECT *
FROM users
WHERE username = :username AND password = encryption_function(:password)
See Encryption and Compression Functions for the encryption functions available with MySQL.
This way, if someone gets your user database, they'll need to decrypt the passwords for them to be useful to break into your application.
Either way, you should make sure the passwords are transmitted over encrypted connections (e.g. SSL). If someone sniffs the traffic, either mechanism allows them to get whatever they need to login.
Yes that would work, as a given hashing function always gives the same result when presented the same input. The only ability your users would loose is password recovery by looking in the db, but that's not the end of the world.
A note however about
it's possible to "de-hash" relatively easily these days.
Choose your hashing function wisely to mitigate this risk - you can go here for some inspiration (tl;dr consider bcrypt, scrypt and pbkdf2)
A criterion that should influence your choice is the existence of ready to use, trustworthy implementations of the selected algorithm, a quick Google search for the language you're using should point you in the right direction here.

Is the MySQL password function vulnerable to this?

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.