I'm creating a MySQL database with registered users, and I'm thinking to use md5 not only for passwords but for e-mails too.
I think this choice can improve user security, but I'm not yet an expert with databases and I'm not sure if this is wise or not!
I hope this isn't a stupid question!
Do you not want to be able to get the email addresses back later on, such as to email them with news of an update? Hashing is a one-way process.
Using a hash for the email address would work in terms of the user entering their email address to get a new temporary password, in that you would have the address right there and then - but if you needed to email them later, you wouldn't have the information any more.
If you store the emails as MD5 digests, you can't email your users anymore...
MD5 is one sided - it cannot be revered. For passwords, this is desireable - no one can figure out the password.
For emails, not so much - you will not be able to send emails to your users, only confirm it is the same as previously entered.
You should not only MD5 your passwords, but add salt value and hash resulting password multiple times, then save salt and hashed string in database. That way it will be harder to guess original password - it's not about your security (cracker can bruteforce passwords same way, but it'll be a little slower, which is good), it's about users security. Many of users use same password in multiple sites. More info in http://www.codinghorror.com/blog/archives/000953.html
You can use a one way hash like MD5 or SHA-2 to sign a message to make it harder to forge or alter, but there's no practical way to convert the hash back into a message.
Related
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I am working on a project that has to have authentication (username and password)
It also connects to a database, so I figured I would store the username and password there. However, it seems like not such a good idea to have passwords as just a text field in a table sitting on the database.
I'm using C# and connecting to a 2008 express server. Can anyone suggest (with as many examples as possible) what the best way to store this type of data would be?
P.S I am open to the idea that this info not be stored in the database if a good reason can be provided
You are correct that storing the password in a plain-text field is a horrible idea. However, as far as location goes, for most of the cases you're going to encounter (and I honestly can't think of any counter-examples) storing the representation of a password in the database is the proper thing to do. By representation I mean that you want to hash the password using a salt (which should be different for every user) and a secure 1-way algorithm and store that, throwing away the original password. Then, when you want to verify a password, you hash the value (using the same hashing algorithm and salt) and compare it to the hashed value in the database.
So, while it is a good thing you are thinking about this and it is a good question, this is actually a duplicate of these questions (at least):
How to best store user information and user login and password
Best practices for storing database passwords
Salting Your Password: Best Practices?
Is it ever ok to store password in plain text in a php variable or php constant?
To clarify a bit further on the salting bit, the danger with simply hashing a password and storing that is that if a trespasser gets a hold of your database, they can still use what are known as rainbow tables to be able to "decrypt" the password (at least those that show up in the rainbow table). To get around this, developers add a salt to passwords which, when properly done, makes rainbow attacks simply infeasible to do. Do note that a common misconception is to simply add the same unique and long string to all passwords; while this is not horrible, it is best to add unique salts to every password. Read this for more.
Background
You never ... really ... need to know the user's password. You just want to verify an incoming user knows the password for an account.
Hash It:
Store user passwords hashed (one-way encryption) via a strong hash function.
A search for "c# encrypt passwords" gives a load of examples.
See the online SHA1 hash creator for an idea of what a hash function produces (But don't use SHA1 as a hash function, use something stronger such as SHA256).
Now, a hashed passwords means that you (and database thieves) shouldn't be able to reverse that hash back into the original password.
How to use it:
But, you say, how do I use this mashed up password stored in the database?
When the user logs in, they'll hand you the username and the password (in its original text)
You just use the same hash code to hash that typed-in password to get the stored version.
So, compare the two hashed passwords (database hash for username and the typed-in & hashed password). You can tell if "what they typed in" matched "what the original user entered for their password" by comparing their hashes.
Extra credit:
Question: If I had your database, then couldn't I just take a cracker like John the Ripper and start making hashes until I find matches to your stored, hashed passwords?
(since users pick short, dictionary words anyway ... it should be easy)
Answer: Yes ... yes they can.
So, you should 'salt' your passwords.
See the Wikipedia article on salt
See "How to hash data with salt" C# example (archived)
As a key-hardened salted hash, using a secure algorithm such as sha-512.
The best security practice is not to store the password at all (not even encrypted), but to store the salted hash (with a unique salt per password) of the encrypted password.
That way it is (practically) impossible to retrieve a plaintext password.
I'd thoroughly recommend reading the articles Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes [dead link, copy at the Internet Archive] and How To Safely Store A Password.
Lots of coders, myself included, think they understand security and hashing. Sadly most of us just don't.
I may be slightly off-topic as you did mention the need for a username and password, and my understanding of the issue is admitedly not the best but is OpenID something worth considering?
If you use OpenID then you don't end up storing any credentials at all if I understand the technology correctly and users can use credentials that they already have, avoiding the need to create a new identity that is specific to your application.
It may not be suitable if the application in question is purely for internal use though
RPX provides a nice easy way to intergrate OpenID support into an application.
In your scenario, you can have a look at asp.net membership, it is good practice to store user's password as hashed string in the database. you can authenticate the user by comparing the hashed incoming password with the one stored in the database.
Everything has been built for this purposes, check out asp.net membership
I would MD5/SHA1 the password if you don't need to be able to reverse the hash. When users login, you can just encrypt the password given and compare it to the hash. Hash collisions are nearly impossible in this case, unless someone gains access to the database and sees a hash they already have a collision for.
So, I am creating a table for failed log in attempts. Should I store the password the person entered as is, or hashed, or not store it at all?
If it is as is, it maybe really similar to the person's actual password, if i store it hashed, what the hell do I want it for? That leaves only the last option. Am I right? Thanks
Any suggestions for this are welcome
why you need the password for? Just store the user's IP , the username to know which username he tried to connect to and the time of the event.
Later since you got the username you can compare with user table if the username and IP is same or similar so you will know if it's user's fault or brute force attemp
what the hell do I want it for?
You might be able to better detect patterns of abuse. For example a bot trying the same passwords against different accounts, brute force/dictionary attacks, and attempts to use leaked account information from other sources. You may be able to correlate different attackers better.
Generally this is considered of marginal utility and not at all worth the risk of storing and exposing this information which in the common non-abuse case is indeed likely to be sensitive.
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.
Will hashing both the username and the password yield any security benefits ?
I meant this scheme :
1.User enters E-mail address
2.Calculate Hash(e-mail) address
3.User enters password Calculate Hash(password) .
4.Match the values to indicate a successful or failed login .
Wouldnt this make it a bit harder to match cracked hashes to the corresponding users.
I dont know if this is already used or if this idea is just impractical for some reason I havent thought of . I didnt find anything in my searches so I asked here.
It would make login credentials harder to crack, but it would also mean that you wouldn't be able to get a clear text version of the user name, which is something that you may well need to do.
The best way to strengthen the security on your login credentials is to use a stronger (ie slower) salted hash algorithm on your users' passwords, such as bcrypt or PBKDF2.
See http://codahale.com/how-to-safely-store-a-password/
I'm no security expert, but it feels like it should add some security. However, you might struggle to communicate with your users that way. You can't email a hash with product updates or monthly invoices.
I'm building a website which allows users to create accounts and access the site's content. I don't want users to log in each time they visit the site, so I'm planning on storing the username and password in a cookie -- however, I've heard this is bad practice, even if the password is hashed in the cookie.
What "best practices" should I follow to safely remember of a users credentials between visits to my website?
Don't ever do that. Throwing around passwords in the open.
Safest method:
Store the username in a database, in the same row a randomly generated salt value, in the same row a hash checksum of the password including the salt. Use another table for sessions that references the table with user credentials. You can insert in the sessions table when the user logs in a date you want the session to expire (eg. after 15 days). Store the session id in a cookie.
Next time the user logs in, you get the password, add to it the salt for the user, geterate the hash, compare it to the one you have. If they match open a session by inserting a row in the sessions table and sending the session id in a cookie. You can check if the user has logged in and which user it is by this cookie.
Edit:
This method is the most popular in use on most sites. It hits a good balance between being secure and practical.
You don't simply use an autoincrement value for the session id. You make it by using some complicated checksum which is hard to repeat. For example concatenate username, timestamp, salt, another random salt, and make an md5 or sha checksum out of it.
In order to implement a feature that involves user credentials in a website/service there most be some exchange of data related to the credentials between the client and the server. This exposes the data to man in the middle attacs etc. Additionally cookies are stored in the users harddrive. No method can be 100% safe.
If you want additional security you can make your site go over https. This will prevent people from stealing cookies and passwords using man in the middle attacks.
Note:
Involving IP addresses in the mix is not a really good idea. Most often multiple clients will come from the same IP address over NATs etc.
You shouldn't need to store the password, just an identifier for the user that your application can interpret to be them.
Things you need to be aware of:
If the cookie is copied, will another user be able to pretend to be that user
A user shouldn't be able to construct a cookie that would authenticate them as another user
A possible solution to deal with these would be to create a one-time key for each user that is changed when they next use the application.
You will probably never be able to remember a user fully securely, so this should only be used if there is no sensitive data involved.
Passwords in any form shouldn't be stored in cookies. Cookies can easily be stolen.
Some browsers already support saving passwords. Why not let the user use that instead?
Storing a hash of the username in a cookie could provide this "remember me" functionality.
However for sensitive areas of the system you would need to know that a user entered the system on cached credentials so that you could offer a username/password prompt before you let them cause any real damage. This could be held as a session based flag.