In my wpf test program,I have a passwordbox,When user try to login and input a string to passwordbox,how to compare this string with encrypted password to validate user's identity and how to make the this process of comparison more safe.
And my confusion is: Should I decrypt password to plain text then compare with user inputed string directly,like use a equation to confirm whether two variables are equal? I personally think if I do it in this way more secure programming skills should be applied,what is this kinds of skills?
well .. when he types it in, it is in plain text ... but you shouldn't store them as text, you'll usually add a salt and hash them, and keep the salt.
Then you'll do the same with the input, and if both hashes match, you let them log in ...
Example:
Password: BadPassword
You then add a salt (you could use a set one, or generate one, google it up).
let's assume your salt is: YummySalt. you then pass passtord+salt to hashing method: Hash(password+salt).
you'll get some hash, lets say : oanuh835930notihaoneu340
you save that in DB, and when the user enters the password, you generate the salt (or just use the fixed one), hash it, and compare that to the hash in DB.
Related
I'm trying to secure my c# app. I know that we MUST store password hash and salt in DB. So my question: How I can compare that password is correct if I use Random salt? (Random salt gives random values each time).
I also have the code below
public static string HashPassword(string p, string s)
{
var combinedPassword = String.Concat(p, s);
var sha256 = new SHA512Managed();
var bytes = UTF8Encoding.UTF8.GetBytes(combinedPassword);
var hash = sha256.ComputeHash(bytes);
return Convert.ToBase64String(hash);
}
public static String GetRandomSalt()
{
var random = new RNGCryptoServiceProvider();
var salt = new Byte[1024];
random.GetBytes(salt);
return Convert.ToBase64String(salt);
}
I am open to other suggestions in general.
I am open to other suggestions in general.
I will preface this post by making a broad point but I believe it is widely enough held to not constitute an "opinion".
If you are doing this "to secure your app", stop now. There are much better solutions like BCrypt, Scrypt and Argon which take care of all this for you and protect against threats that most people haven't even considered. These of course include salt(s) internally, so understanding what they are for and how they work is still a useful endeavour. For approximately the same amount of code, you will be handling the credentials a lot more securely than the posted code indicates. Google them for details.
If you are just doing this as "an exercise to understand how it all works", continue reading.
So what is salt exactly and why is it useful for protecting security?
Salt is additional entropy that is not part of the user's password, but is instead known to or invented by the server at the time the password is hashed and stored. The generated salt must be known to the server when validating your password. There are many ways it can be stored. It may be the first/last/middle/every8th/whatever n characters of the password hash stored in the database. It may have its own separate field. It may even be based on other facts immutable like Primary Keys of the user record itself.
The threat model that this protects against could be described like this. Consider a database that was compromised and now held by a malicious actor. The challenge is, given the malicious actor holds the credentials (in hashed form), can we stop them from guessing people's password (at least without trying some sort of dictionary or brute force guess attack.
If you thought hashing solved that problem, then I will give two possible scenarios:
1. Two users may use the same password
If the password is hashed but not salted, then two users who choose the same password will end up with the same hash. And even if the password isn't "terrible", the other user may reveal your password by whatever they entered as the "Password Hint". If the passwords were salted, then the fact that the password hint gave away the other user's password doesn't leak the fact that the same password would work on your account.
2. Rainbow tables
If you have enough time and compute power, you can generate (or download) a set of rainbow tables. These are basically key-value pairs, where the key is the hash and the value is the original password. These are generated in reverse. That is to say, take a string, hash it, add the hash as the key and the original string as the target. To lookup, you simply lookup the hash key and see what value comes back. Near instantly. With a long enough original string though, it won't have been pre-computed so it won't have a hit in the rainbow table. If I know the salt you are using and the hashing algorithm, I can still do my own dictionary attack or brute force attack, but suddenly I am required to try each guess in turn until I am lucky, so if your password is good, I will not find it in "reasonable time".
The precise answer to your posed question
How I can compare that password is correct if I use Random salt?
Your verification process needs to know or derive exactly what exact salt value was chosen for the hash process. The salt may be randomly generated, but if so it needs to record the exact value used.
First , you have to get salt in database by username , then hash it with posted password , finally compare it to password stored in database
I attemt to write a program, with which you can login to a remote website. For some people having multiple accounts, I try to make it easy for them and store account data in IsolatedStorage. At the current state of my code, the password is just entered in a TextBox and as soon as it's stored converted to a MD5 hash.
Now I'd like to refactor this to proper code, but I got stuck.
A PasswordBox exposes its data through PasswordBox.SecureString and PasswordBox.Password.
So when clicking my save button I'd perform something like
public void OnClick(...)
{
var password = passwordBox.Password;
// store it somehow (e.g. custom MD5 encryption)
var savePassword = passwordBox.SecureString;
// store this string somehow, but how?
}
Here my questions
As soon as I put the plain password from my PasswordBox into var password, is there something visible in memory? Would some hacker be able to make this plain value visible through reflection/debugging? Which code makes these strings actually visible? And what do I need to be aware of?
How to handle SecureString of the PasswordBox?
I'm a bit overwhelmed by all this stuff and I can't figure out the essence of how to handle passwords in an application properly, yet.
I'm not pleading for a whole solution and running code. I'd just be glad, if someone can get me started. And also, I don't want an enterprise solution. I'm just searching for one, which is easy to implement and as save as possible for the effort I put in.
Do you really need the password to be reversible?
A safer way to store it is to salt and hash it.
User: JOHN
Password: (starts out as) myUserPassword667!
Then use some sort of database unique code against the user in the DB. Lets say a GUID.
Now you have abcd-1234-12-1212121ab as the uniquifier for JOHN
so you now have a base password(before hashing)
myUserPassword667!abcd-1234-12-1212121ab
You can now Hash this with one of the SHA or other hashing algorithms in the System.Security namespace.
Now you internally have some Salt that you Apply to your hashing algorithm... (Part of your code only)
MySecretSaltWords559BC
then store the Result as either a Base64 or Binary in your DB.
Ab09l\311sas== (simplified)
Next time the user logs on you find their record in the DB, you get your Unique code that was used when you generated the account and attach to the password they entered.
Hash the entered password with the same technique and binary compare the result, then you don't need to ever store their password. If the hashes don't match you don't have the same password.
I have a method that is used to encrypt the password and store it to database as below :
public static string Md5Encrypted(string password)
{
byte[] pass = Encoding.UTF8.GetBytes(password);
MD5 md5 = new MD5CryptoServiceProvider();
string strPassword = Encoding.UTF8.GetString(md5.ComputeHash(pass));
return strPassword;
}
Now I want the method that decrypt the password that I get from database which was encrypted by above method while storing it. I don't know how to make it. Anybody can help me please?
MD5 is a hash function (not an encryption) and is irreversible. That is, you can't compute the original value from a given hash.
Update: I recommend this article that describes how to store password hashes securely. There's a C# implementation as well.
http://crackstation.net/hashing-security.htm
MD5 hash function is irreversible and cannot be decrypted,If you want to check the Username and password during login then do this..
1.While registering a new user, Hash the password and store it in database.
2.During login,Hash the password entered by the user
3.Now,Compare the password entered(Hashed ) with password stored in database(Hashed)
4.If both of them are same then allow user to login else display an error
You can't decrypt this, because hashing is a one-way function - you can't take a hashed value and turn it back into the original value.
Since it looks like you're dealing with passwords and I therefore assume this is some kind of logon mechanism, this is (probably) OK. What you need to do is hash the password (as you've done), and store the hashed value when your user registers on your website. When the user returns to your site, you take the password they enter, hash it (using the same method), and compare the hashed value with the value you stored. If the two hashes match, the correct password was entered.
Salts
There's a problem with hashes, in that the same input value always produces the same hashed value (otherwise the above mechanism for logon wouldn't work). Unfortunately this means that generating hash values for, say, a dictionary of common passwords is a trivial exercise. If your database is compromised, an attacker can then compare all the hashed passwords you've got stored against his previously computed values, and if he gets a match then Bazinga! he's got into your data.
To defend against this, what you can do when you do your initial hashing is at the same time generate an extra bit of random data that gets mixed in with the password as it's being hashed. This is called a salt (or less commonly a nonce). Rather than reproducing some code to do this, at this point I'm going to direct you to blowdart's book Beginning ASP.NET Security (Amazon UK | Amazon US), which has discussion of all this stuff - hashing, salting and 'proper' encryption.
I have a simple password encrypter that gives me a hashed/salted password to store in my database when a user registers. Code:
public static string GenerateHashWithSalt(string enteredPassword, string enteredSalt)
{
string sHashWithSalt = enteredPassword + enteredSalt;
byte[] saltedHashBytes = Encoding.UTF8.GetBytes(sHashWithSalt);
System.Security.Cryptography.HashAlgorithm algorithm = new System.Security.Cryptography.SHA256Managed();
byte[] hash = algorithm.ComputeHash(saltedHashBytes);
return Convert.ToBase64String(hash);
}
When a user logs in, I presume I can't simply put the entered password back through this code and compare as it would give me a different result. How can I simply compare the stored password against the entered log in password?
When the account is created, you would have a password hash column, which would be populated by GenerateHashWithSalt(password, salt); where the password is provided by them and then the salt is randomly generated. The salt would then be stored alongside the password hash.
Then, when you need to see if a username/password is valid, you'd use storedpassword == GenerateHashWithSalt(providedPassword, saltFromDb) or some such. If they come out the same, then you know they entered the correct password
I wrote up a quick tutorial on how salted-hashed-password-equivalent schemes work. However, based on the fact that you are asking the question I should caution you that this is only the first step in ensuring a secure logon process. You should hire a security expert or purchase an off-the-shelf solution rather than attempting to roll your own if you are a beginner at this. The number of ways to make an inobvious mistake that makes the system insecure is enormous.
http://blogs.msdn.com/b/ericlippert/archive/tags/salt/
If all you need is a way to compare passwords, maybe this will help: encryption/decryption
There are a couple of steps to do this correctly.
First you need 3 things:
A password provided by the user. (let's call it p)
A random string of characters that you create. This is known as the salt (we'll call it s)
A cryptographic hash function (well call it h(x))
With the above three things we can calculate h' which is what we want to store: h' = h( s + p )
The user's password is never stored. We only store s and h' in our database.
The salt doesn't need to be encrypted. It just needs to be be unique for every password in the database.
When the user tries to log in again in the future you will recalculate h' using the original salt that is stored in the database. If the new h' is equal to what is in the database then the user's password is the same.
I am creating a login screen for an application in C#. In my login screen I am reading the username and password from the database and checking whether the entered username and password are correct or not. I need the password to encrypt while I am reading the password form the database. Can anyone explain how encryption and decryption works.
Whether I have to store the encrypted value in the database for reading.
Right now I have two fields
column names: username password
values: admin password
Should I store the encrypted value of the password in another field in the login table?
First: The common approach now is that store the salted hash of the password, instead of the plain-text password itself (SHA-1 and better hashing algorithm are preferred, avoid MD5 because it's not safe any more) . When the user login, you recalculate the hash of the input string, then compare it with string stored in the database.
EDIT: why shouldn't you use encryption for password? Because when the attacker knows the key of encryption, all of you passwords will be exposed (That's very bad). If you using hash, he just can guess one-by-one (and this is not easy). Otherwise, hash algorithms, in general, are faster then encryption, you'll take the performance benefit.
EDIT: why you should store salted hash, instead of a hash? Because hashing algorithms are guaranteed that if you hash identical strings, the result is the same. This may lead to a problem is that, when attacker see the same hash values, he can guess that the texts were the same, and this gives chance for him to get the original password.
Salt means that besides the original text, you put some random text, and therefore, two identical strings will generate different hash values
Take a look at this: http://www.obviex.com/samples/hash.aspx
In case of the user forgets his password, you can use the reset password function, which many sites are using:
The user requests a password reset
An email contains a special link (include a secret token/PIN) will be sent to registered email address, that allows user to reset his password.
A randomly created password will be sent again to user, then he can login and change his password.
UPDATE May 14th 2012: The answer seems to be old, and not completely true. People are moving to more secure hashing-encryption algorithm for storing password. One of notable solution now is bcrypt, and another (new and promising) is scrypt.
The advantage of these encryption? They're slow! Much slower than hashing algorithm. With the power of GPU (for example, CUDA from nVidia), cracking the hash value is not impossible now, and the slowness can make it much harder to crack these encryption.
You can find more about bcrypt at: http://codahale.com/how-to-safely-store-a-password/
Second: You should separate the users table (contains user profiles, such as full name, DoB, address,...) and logins table (Which contains user name and password, and some special attributes). This will lead to better management and reduce the risk of exposing sensitive information
Along with given advices, there are other methods to protect passwords:
One-Time Password: In spite of
implementing salted hash, passwords
are still stored on hard disk and
are prone to be cracked. So a better
approach is required here. In
contrast with static passwords,
one-time passwords are changed each
time a user logs on to the system
and usually users should carry a
small hardware used for
synchronizing with server. Mainly
there are two types of OTP: (Visit Safer Authentication with a One-Time Password)
Time-Synchronized
Counter-Synchronized
Using BCrypt which uses a variant of the Blowfish encryption algorithm's keying schedule and contains a work factor, which lets you determine how expensive the hash function will be. In order to get familiar with bCrypt, visit: http://codahale.com/how-to-safely-store-a-password/
In C#, you can use BCrypt.Net library which is a port of iBCrypt library: read the following article to understand how to get this library up and running in Visual Studio.Net:
Using BCrypt in a .NET Application – Why it’s better than SHA or MD5.
Of course, there are a lot of discussions about this algorithm in SO, search and study more about this.
Are you implementing your own authentication mechanism? You can use already existing System.Web.Security microsoft authentication. By using Membership class you can validate user password without retrieving it from the database. This way you will be able to store the salted (encrypted) password in your database. Just use Membership.CreateUser and Membership.ValidateUser.
If you don't need (performance wise or proprietary implementation) use existing implementations and save time.
The password should be stored in database with encrypted value itself. And when user tries to login, encrypt the password with the same algorithm and then compare it to the value in db.
Md5 is usually used for password encryption as it cannot be decrypted. Incase the user forgets the password, he cannot retrive it back, but it can only be reset.
Hope this helps !
You can encrypt the passwords in many ways.
One of the way is using the MD5 encryption. Let me show you one of the encryption method that I am using.
#region Encrypt
public string Encrypt(string simpletext, string keys)
{
try
{
XCryptEngine xe = new XCryptEngine();
xe.Algorithm = XCrypt.XCryptEngine.AlgorithmType.DES; //DES = Data Encryption Standard
string cipher = xe.Encrypt(simpletext, keys);
if (cipher != null)
return (cipher);
else
return null;
}
catch (Exception ex)
{
throw ex;
}
}
#endregion
#region Decrypt
public string Decrypt(string simpletext, string keys)
{
try
{
XCryptEngine xe = new XCryptEngine();
xe.Algorithm = XCrypt.XCryptEngine.AlgorithmType.DES;
//Console.WriteLine(xe.Decrypt(simpletext, keys));
simpletext = simpletext.Replace(" ", "+");
string cipertext = xe.Decrypt(simpletext, keys);
if (cipertext != null)
return (cipertext);
else
return null;
}
catch (Exception ex)
{
throw ex;
}
}
#endregion
you need to use reference for XCrypt to use this.
using XCrypt;