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.
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'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.
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.
I'm creating a service that will gather user data such as username, name, email, login password. How do I securely store this data? One thing I was thinking is store it encrypted in the DB so that if anyone gets access to the DB they won't be able to use the data.
But that arises two issues - #1 - much much slower search of the DB and #2 the encryption key will still be stored in the Perl script that will encrypt the data submitted by the user so if someone gets access to the whole server they'll still be able to decrypt all data.
So I was wondering what do services such as Twitter, Facebook, Hotmail, etc. use to securely store data?
BTW: as I said I'm working with Perl/MySQL.
Thank you all nice people!
You should try and avoid encrypting everything in the database. At the very least you will have to figure out which fields are being used for searching, relations, sorting etc and leave those unencrypted. You have to consider layers of encryption based on who you are hiding the data from. It would also help if you are clear about the differences between one way hashing (MD5, SHA), symmetric encryption and asymmetric encryption.
Encrypting passwords in the database makes sense because it hides the passwords from the dba or anyone with the ability to query the db directly. Actually, passwords are not encrypted, they are hashed. This way you can never recover a password, you can only generate a new one.
Data that needs to be recovered will be encrypted, so that it can be decrypted. There are various algorithms for doing that and they have different attributes of strength and cost (in terms of processing time and memory). You should choose one which suits your purpose.
The thing here is that encryption and decryption need to be done in the application and not in the database. The reason for this is that at some point there might be an open network between the database and the application servers and any data transmitted between the application and the database could be sniffed.
In deciding between symmetric and asymmetric encryption, there are two factors. One is for how long does this information need to be kept secure. If it is a bid on an auction that is going to end in 2 days, you may use symmetric encryption, because it ideally will not matter if people figure out things after that. Credit card numbers typically do not have to be kept safe. If you are storing the expiry date and the ccv numbers of the card then those have to be kept safe, typically for years. In that case you have to use asymmetric encryption.
In encrypting the whole file system it is not the performance degradation that you have worry about mainly. As far as I have seen, it requires a person to key in the correct password when OS is booting, and that requires physical access, and persons who can be trusted to know the password staying as close to the servers as the SLA requires. In this it is like setting a bios password or a grub password. If you indeed encrypt your file system, make sure to verify this or find a way around it.
Others have pointed out that encryption will incur a slowdown. How much will depend on lots of different factors, so you'll need to benchmark your code.
But in reality the most important thing to protect is probably the password since if that is compromised then the users' accounts on other services could be compromised as well since people tend to reuse the same username/email/password combos.
Fortunately passwords are easy to secure. Use a 1-way hash like SHA1 with a salt (to protect against rainbox tables) and never store the actual password in your DB. Store the salted-hash. Then when the user logs in you can check the pw they give you against the hashed one to make sure it matches without ever having to store what their pw really is.
See my answer here. The gist of it is that you can add security, but there is no 100% foolproof way to avoid a compromise of (some of) your user information if your web application is completely broken.
Encrypting the filesystem on which the database is stored minimizes many other types of vulnerabilities. Encrypting data in the database protects you against those and also against a user breaking your DB password. Encrypting data in the database with a hardware token provides the best protection but is inconvenient.
You have a few options:
You can encrypt the data in the middle tier
You can encrypt the database
You will encounter slower searches either way. In both cases, the encryption key is not included in the backup file set.
My university has a portal which students use to register for classes. If you want to get into a full class, you have to keep checking the portal, and sign up when the class has an opening.
I wrote a tool that can check for openings and register automatically, but it needs the students university username and password. These passwords are tied to email accounts, network shares, server logins, and most every other university service.
Is there any way to do this securely?
In security, the most important thing is the "threat model". What kind of attack do you fear?
somebody may steal the computer where this program runs on: put the computer in a locked room.
somebody may hack into the computer and read it from memory: use firewalls and other protection against remote attacks
other users may read the hard disk where the password is stored: only store the password in memory (which would require re-entering it every time you start the program)
the super user may read the password even if it is in memory: only run the program on a computer where you trust the superuser.
etc.
Unfortunately, this is not really possible -- at least not the way you want to do it -- unless the university provides a key-based authentication API. You could always ask them nicely, but they'll probably be too busy to help. If you give your users full disclosure and keep your server secure, it should be enough.
Actually, there is one way to do it through the web without storing passwords -- you could use a Java or Flash app. Unfortunately your users would need to leave the browser open while the app does its work, but this way you wouldn't need to store the information.
You could encrypt the password strings when you store them and then decrypt them when you need to try logging in. Simply generate a symmetric key and use that to encrypt and decrypt the passwords for storage and retrieval (respectively).
You can't store them entirely secure because you'd need to be able to encrypt and decrypt so one-way hash algorithms like MD5, SHA-1, SHA-2 wouldn't suffice. You could look into something like DES or Triple-DES encryption.
I do not think there is. As Martin pointed out one way encryption won't do it for you. Also this will create a maintenance nightmare for you - every time a user changes password you will have to update your data.
I think to make it really work you have to change the design: find a way to do the registration without the user password, i.e. talk to the owners of the app if they would give you an account through which you can do registration on behalf of somebody else