I read so many articles left and right about password encryption but it seems that they are mostly 2-4 years old.
I wonder if there have been new findings on what methodology has already been cracked and mainly what's the more secured way to encrypt a password for user logins on a public website today in 2013.
The main goal is to do a ONE WAY (not decryptable) secured encryption so using hash or not, using salt or not, that's what I'm hoping to learn here.
======================
Other question:
Does it make sense to change the SALT for each password instead of using the same one for all?
Here is an excelent site that talks about password hashing. I think it covers all of your questions: https://crackstation.net/hashing-security.htm
Does it make sense to change the SALT for each password instead of using the same one for all
A salt needs to be a different random string for each and every password.
Note the word random.
Usernames, the system clock and other low entropy data is not advisable.
using salt or not,
Hashing password without using a salt leaves you open to parallelization of the attack.
Not only does it allow rainbow tables, but it also allows the attacker to hash easy to guess passwords and compare the hash against all entries in the database.
This means that an unsalted database with 1,000,000 records in a million times easier to crack than one with 1 entry.
-Not good-
Read up on the subject at security.stackexchange
The leading expert on these subjects stalks the ranks at https://security.stackexchange.com
The canonical answer to your question is here: https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords
Thomas Pornin is a well known cryptographer and writes very informative, insightful and entertaining answers; check out his user profile. https://security.stackexchange.com/users/655/thomas-pornin
And don't miss out on the Chimps.
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.
Is there a security benefit to having an application wide salt as well as a salt that is specific to each user? So when the one way hash is computed the two salts are combined (the one from users database record and the one that is compiled into the applications code).
This way if the database is compromised the attacker wont have all of the information needed to try and crack the passwords.
Decided to go with BCrypt in the end, thanks for the help guys.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have a table in the backend where I store the password after converting it to hash.HASHBYTES('SHA2_512', 'Welcome1'). It is stored in the backend like this:
0xDA07C08A2C2EF3710E688BFF476A8A09D52D6D34B6EE3C41A4B1F58F2949792EF20079565CA0D78E2758B33B50A13C9829C08BDF670DC802E627F289364D203A.
Now I want to show this password from backend in front end after converting it back to 'Welcome1'.
I am not able to do that and getting password as system.byte[]. Can anyone please help me to get 'Welcome1' as the value in front end.
The requirement is to create a page for admin where he can see all the users,their details including password.If he clicks on an user(link button) all his details should appear in the text boxes including password.I understand it is not a good approach to show the password,but would like to know the all the options we have.If there are not any,I can let the business know this is not possible.Thanks so much for your help.
Let me summarize my answer first and then go into more detail:
You can't!
More importantly, you shouldn't even try!.
By hashing the password you have performed a one-way calculation/transform from the password to something else, usually a sequence of bytes, which is again usually represented as a string of hexadecimal characters.
The "one-way" part of this should not be taken lightly.
First of all, can you reverse a hash? No, you can't. But you can guess what the value could be.
How then could you make this guess?
There are several methods available to you:
Brute-forcing
Exploiting a weakness
Rainbow tables
Brute-forcing
Brute-forcing would basically mean that you would try every possible password until your hashing function returned the same hash. At that point you have a password that might match the hash you have in your database. Depending on the password you might not have the password, but again depending on the circumstances this might not mean much.
Brute-forcing good hash functions, however, is infeasible, unless you intend for your computer to stay online for many times the life of the known universe, past, and future alike.
For brute-forcing SHA-512 it would take ~3.7 * 10^64 years to complete (not verified, lifted from #emboss' excellent answer here).
Exploiting a weakness
The brute-force attempt might be shortened down drastically, however, if there is a weakness in the algorithm that you can exploit. Unfortunately, no such weakness is currently known for SHA-512.
Salt
Unfortunately, if you haven't used a salt to add some randomness to your hash, you are actually weak to the next possible way of breaking a hash.
A salt means that for evey password you want to hash you generate a random value as well, you then combine the password with this random value, then you perform your hash function on this and get your hash. You then store the random value + the hash in your database.
More below in the rainbow table section why this is a good idea.
Rainbow Tables
Rainbow tables mean that you keep a very large table of all known hashes for all known password and character combinations up to a certain length. You could then simply look up the hash in that table and get back a matching password. Just as with the brute-force you would get a password, and depending on the chance of collisions, it might not be the password, just one that hashes to the same value.
These tables, to boot, is very large. For a SHA-512 rainbow table up to 9 characters you are talking close to a terabyte of data (from this answer by #LateralFractal).
For even longer passwords the size of these tables quickly spiral out of control.
Now, I mentioned salt above. If you have a salt for each password, and each salt is random (if you use the same salt for every password you're in no better shape), then you basically need a rainbow table for each salt, meaning you have to generate these tables yourself, for each password you want to break. This also takes a long time. Not universe-lifetime long, but impractical long for most passwords and their worth.
Conclusion for how: You can't, you simply can't. There is no practical solution to reversing a hash back to its password.
Why shouldn't you be doing this?
The sole reason for hashing a password (usually with a salt as well) is to avoid actually storing the password to begin with.
Many users (most?) use the same passwords on a lot of sites so if one site is breached, and a data-dump is made available, and the passwords are either stored in a reversible manner or using basic hashes that can be reversed using rainbow tables or brute-forcing, then that users accounts on many sites suddenly become compromised.
Additionally, and this is important for you, the owner of the breached site won't be looked upon with happy eyes as they purposefully used a broken way to store the password (hashes) in their database. You don't want to be that guy.
So this is why you shouldn't be doing this. By this I mean that once you understand that you cannot reverse the hashes back to their passwords your response should not be to switch to some other way of storing the passwords that allow you to reverse it.
The entire point of hashing the password for storage in the database is that it's NOT reversible. You can't get the password back from the hash. You shouldn't have a way of getting the password back to the plaintext version in case someone manages to get ahold of your data
Im making a program in C# that has passwords and I need to encrypt them. So far I flip the string backwards (so hello becomes olleh) and then I use a loop that loops through each character, and the loop inside it loops through another string that has the converted letters to see if they match. Using this, hello = Ghh#$ so it works fine. So anyway, are there any extra stuff I can add to it? PS what is salting and how is hashing one way?
Rule one of cryptography is don't write your own encryption scheme. Instead use a library such as http://www.cryptlib.com/why-use-cryptlib-10-good-reasons which has bindings for C#.
For more information check out the first answer to:
https://security.stackexchange.com/questions/2202/lessons-learned-and-misconceptions-regarding-encryption-and-cryptology
First off, the difference between encryption and hashing is, at a high level, that encrypted data can be decrypted with the right key, whereas hashed data cannot be retrieved except via brute force methods like pregeneration or rainbow tables.
Hashed passwords are validated by hashing the user's input each time that they log in in the same way that you do when they create the account, and comparing the result of the hash. For any given input, the hashed result should be the same.
Obligatory rant:
There is a good argument to be made that passwords should always be hashed using a cryptographically-strong algorithm. You may hear the excuse that "my application/web page/etc is not all that important, there is no sensitive information there", or "I'm just learning so it isn't important", but the fact is that if I can crack the security of one website, or you leave your machine logged in and I steal your password file from your "educational" app, I can take all of the user's email addresses and virtually guarantee that at least a few of them will use the same password for that gmail or yahoo account. I can then send reset requests for just about any site that their email tells me they have an account for and get access to those also. So it is very important that no matter what software you are writing, if it stores passwords, you should do the responsible thing and salt + hash them properly.
Salt: http://en.wikipedia.org/wiki/Salt_(cryptography)
Hashing: http://en.wikipedia.org/wiki/Cryptographic_hash_function
Simplistic Example:
var salt = "abc123";
var encryptedPassword = HashingAlgorithm("password");
var encryptedSaltedPassword = HashingAlgorithm ("password" + salt);
Console.Writeline(encryptedPassword);
Console.Writeline(encryptedSaltedPassword);
writes out
aIdekXieklKq309nasdf
dfk#cxk)8lkdfesijcde
The point of salting your code is to prevent dictionary attacks. If anyone figures out your HashingAlgorithm, they can brute-force run through every word in the dictionary and figure out that "password" hashes to be "aIdekXieklKq309nasdf". If you salt your to-be-encrypted words, they'd have to know your salt word too.
Also, it's good to hash your passwords into a database instead of using some two-way algorithm, that way anyone (including you and your co-workers) having access to the database can look and see what your users use as passwords (since a lot of users tend to reuse the same passwords on multiple sites).
I want my application to save the password encrypted in a database or in a text file.
How can I do that assuming that the database or text file can be open by anyone?
Duplicate
Encrypting/Hashing plain text passwords in database
Not duplicate
I'm asking for code specific for .NET
EDIT: I'm saving the password for later use. I need to decode it and use it to login.
It doesn't have to be super secure, it just needs to be unreadable to the human eye, and difficult to decode with a trivial script.
StackOverflow readers don't know how to write secure password schemes and neither do you. If you're going to do that, save time by sticking with plain text. From Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes:
Rainbow tables are easy to beat. For
each password, generate a random
number (a nonce). Hash the password
with the nonce, and store both the
hash and the nonce. The server has
enough information to verify passwords
(the nonce is stored in the clear).
But even with a small random value,
say, 16 bits, rainbow tables are
infeasible: there are now 65,536
“variants” of each hash, and instead
of 300 billion rainbow table entries,
you need quadrillions. The nonce in
this scheme is called a “salt”.
Cool, huh? Yeah, and Unix crypt —-
almost the lowest common denominator
in security systems —- has had this
feature since 1976. If this is news to
you, you shouldn’t be designing
password systems. Use someone else’s
good one.
Use BCrypt - Strong Password Hashing for .NET and Mono. It's a single cleanly written .cs file that will continue to meet your needs as password cracking computers get faster.
BCrypt - Strong Password Hashing for .NET and Mono
Triple DES is one way to do it, as long as you mean "A password that my system needs to be able to recall in order to access a resource". If you mean the password is something a user needs to be able to gain access to your system, probably don't want encryption, just a hash will do. When you store the hashed password value, it is useless to anyone with direct database access, but can still be used for authentication. All you do is compare the stored hash against a hash of the incoming password. If they match, then you grant access.
It isn't perfect, by any means, but it is the way 99.999% of people store their passwords.
If you want to argue that you wish to provide the password back to a user if they lose/forget it, then please don't. Issue them with a temporary password (which you store hashed in the db) and get them to change it on first login.
Use Data Protection API either with the user or machine store (e.g. different key per account your program/database server runs under vs. one key per machine). This will help you decode the passwords later and you don't have to remember or store any encryption keys. The downside of it is that when you reinstall the system/delete the account you won't be able to recover the data, I believe.
If you use encryption for securely storing passwords, you'll need to store the encryption "key" somewhere, too. This will be the "weak link", since if someone gets hold of the encryption key, they will be able to decrypt the encrypted passwords.
Since this is passwords that we're talking about here, a much better solution is to use a one-way hash. You hash the password when the user first creates it (preferably hashing with a salt value) and store the resulting hash value. Since hashes are one-way, no one can reverse the hash to the original plain text value.
To check that a users password is correct, you simply ask the user for the plain-text password, hash their input again and compare the resulting hash value with the hash value you have stored (taking salts into account of course). If the two hash values are the same, the user has entered the correct password.
Please see the following links for further info:
Hashing Password with Salt
For encryption (if you need to use that), I'd use Rijndael (AES).
Based on your question I can see two approaches depending on why you are storing the password.
A. if you only need to authenticate using their password and nothing else.
In that case, going using an algorithm that is not reversible (Hashing) would be your best choice. You will need to make sure of a couple of things:
Make sure that the connection is encrypted when transmitting the password from the client to the server. This will prevent it from being sniffed out. This is pretty trivial to do with web applications since the web server is doing the heavy lifting for you. If not it gets a lot tricker and is the subject of an whole other question.
Choose a solid hashing algorithm to prevent collision. I would recommend SHA-256 even if it does provide a larger result than SHA1 or MD5. The reference from Microsoft on using their implementation of the algorythm is here.
Salt the password to prevent attacks using rainbowtable (i.e. looking up the password in large table with the precomputed hash and the associated password in clear text). The answer here (sited in your question) gives good pseudo code in Python on how to do it. There is also a good example of .NET code here.
B. if you need to be able to read the password for each user for other purposes than authenticating the user.
This case is easy if we are only talking about storing a password (or any kind of sensitive information) on a single computer (server). If that's the case, using the Microsoft Data Protection API would be a good solution since it is tied to that computer and (depending on the way you work) the user under which you application runs and takes care of the worst of the job for you (creating, storing, and using keys). You can find some code reference from Microsoft here. If you need it on more than one system and are not willing to enter the password on each system you install on your application then things get a lot more complex because you need to implement a lot of it from scratch. That would be the subject for another question I would think.
If you need to decrypt the password for later use and it doesn't have to be SUPER secure, then use the method here:
http://support.microsoft.com/kb/307010
It's well documented, and easy to understand.
do you need to encrypt it ever again? otherwise use a hashfunction to encrypt it and encrypt the password given by the user with the same hashfunction and look if the hashes are equal.
The reason for not using a 2-way-encryption is that one cannot decrypt your key - since a good hashfunction has collisions.
Personally, I would use something that has one-way encryption - MD5, SHA1, etc...
You can use the FormsAuthentication class with it's HashPasswordForStoringInConfigFile method. When validating the user, encrypt the entered password and compare it with the stored version.
Like ocdecio I would use TripleDes, I would also save the salt in the database too. The key for me is usually hard coded, but the salt should change for each encrypted item.
If you just need the password for an internal authentication process, you should not save the actual password, but save a hash of this password. When you need to check if a password is valid, you'll have to run the hash function on provided password and compare it with the hash you stored in your database/file. You can never find the original password from the hash.
If you need to keep the original password, you'll have to encrypt it. You can use for example a public key infrastructure if you have a process that writes the passwords (public key) and another one that reads them (private key).
Do you really need to be able to retrieve the password itself? If you're storing a password for the purposes of authenticating someone (or something), you should rather hash it (with salting) and then compare that hash to the hash of the password supplied by the party wishing to be authenticated.
If, on the other hand, you need to store the password in order to be able to retrieve it and supply it to some other authentication service later, then you might want to store it encrypted. In that case, use any decent symmetrical encryption algorithm you can, such as TripleDES or AES or Blowfish.
Briefly:
Get a big random number which you will keep private and only your application code will have access to.
Encrypt the password + random number with an ancryption algorithm like SHA1, most programming languages have a cryptography framework.
Store the hashed password.
Later when you want to check inputted passwords, you can rehash the user input and compare to the "virtually" undecipherable stored passwords.
Here's a string encryption article with example code .NET
http://www.devarticles.com/c/a/VB.Net/String-Encryption-With-Visual-Basic-.NET/3/
There is no need to use anything fancy, because anyone with a little bit of skill and determination will break it anyway.