Password encryption - c#

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;

Related

How can I check that password is correct if I add random salt?

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

Verifying Passwords via Hascode

After research I have found out that using hascode to verify password on login page is more secure but can anyone give me some insights code wise how to achieve it ?
I won't write code for you, but I will explain briefly how it works.
First, understand the difference between hashing and encryption. If you don't realize there is a difference, read this: Fundamental difference between Hashing and Encryption algorithms
By default, your password is in plaintext, which is bad. Ideally, you want to be able to store that password in a non-plaintext way so that you can compare it to data that a user sends you. To do this, you can either store an Encrypted password or a Hashed password.
If you choose to store an encrypted password, that implies that you intend to someday retrieve the original plaintext password (which, really, you should never need to do). Additionally, you need to store the key somewhere, and it gets messy (because you don't really want to store THAT plaintext either, so you encrypt it, but then you need ANOTHER key, etc.), so let's just assume you don't want to go this way.
If you choose to store a HASHED password, then what you are storing is a fixed-length representation of that password. A human cannot determine the original password simply by looking at the hash (which is good).
On the client end, then, you still have that plaintext password that they need to submit. This is where encryption comes in. You will want to encrypt the connection between the client and server. The user submits their plaintext password, it gets encrypted so that nobody can understand it, your server decrypts it, and then immediately hashes it. At this point, you may now compare that hash to the one stored in your database.
Please note that hashing the password client side and assuming that encryption is no longer necessary is NOT secure.
Convert given password into its hash:
using System.Security;
using System.Security.Cryptography;
...
public static String GetHashValue(String password) {
// You may find useful to add "salt" here:
// Byte[] buffer = Encoding.ASCII.GetBytes(password + "some const irregular string");
Byte[] buffer = Encoding.ASCII.GetBytes(password);
// I've chosen the strongest (but the longest) hash provider
using (SHA256 provider = SHA256Managed.Create()) {
return String.Join("", provider.ComputeHash(buffer).Select(x => x.ToString("X2")));
}
}
then try to find user by his/her login and password hash:
select permissions,
...
from Users
where login = #prm_login and
password_hash = #prm_password_hash
Note, that you don't store password (e.g. "123") in the database, but the hash (e.g. "A665A45920422F9D417E4867EFDC4FB8A04A1F3FFF1FA07E998E86F7F7A27AE3")

Decrypt method from encryption function

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.

BCrypt generating different hashes given the same salt, string, and factor

Using one of the C# implementations of BCrypt to hash passwords and store them into a SQL database. However when I return to validate against the hash string BCrypt generates a different hash than the one in the database to compare to. The salts are visibly the same as well as the factors.
Here is what I know
$2a$12$vF/1s3MqIzHwnDshyzH/rOYUelofrj4UWv./vzWqk4o2K0uwhix7W is actually "Qwerty123" and its stored in a column which is initialized to be [nvarchar] (200).
When I use the BCrypt.Verify() or BCrypt.CheckPassword() depending on the implementation, I trace it until just before it makes the comparison and the hash that it is about to compare to the before mentioned one is $2a$12$vF/1s3MqIzHwnDshyzH/rOKVRePZSXFXaIpDv6.IPkbPEoOxZgSEe
If you look close you can see that the salts and the factor parts are the same. Any idea what could be causing this?
The explicit implementation I am working with can be found here http://bcrypt.codeplex.com/
My question could be related to ASP.NET MVC 3 app, BCrypt.CheckPassword failing
Suggestion for testing
private void FindWhatsFailing(string password) //password = Whatever you're passing in to verify BCrypt is working
{
const string expectedpassword = "Qwerty123";
if(expectedpassword != password)
{
Debug.WriteLine("My password isn't what I thought it was");
return;
}
string hashed = BCrypt.HashPassword(expectedpassword , BCrypt.GenerateSalt(12));
if(!BCrypt.Verify(expectedpassword , hashed))
{
Debug.WriteLine("Something is wrong with BCrypt");
return;
}
/// ... Test hashing password, compare to hash of expectedpassword, verify password against hash of itself and expectedpassword
Debug.WriteLine("Everything worked, maybe the database storage is off?");
}
If the Bcrypt.Verify isn't working in this example for you, I have no idea what's wrong, but I'm guessing Bcrypt isn't actually the issue here.
The problem was the input to Bcrypt. I was using a Multiview and MultiViewPanels to collect user data(of which a password), allow user to verify all the data, then on the last MultiViewPanel add the user to the DB and in that process there were postbacks. After some research I found that password fields do not retain their text property after postbacks for security reasons and because I was passing txtPassword.text to Bcrypt this was the problem. This makes a new problem for me to look into.

C# Reading back encrypted passwords

I'm using the code below to save a password to the registry, how do I convert it back? The code below isn't mine but it encrypts well.
Thanks
using System.Security.Cryptography;
public static string EncodePasswordToBase64(string password)
{ byte[] bytes = Encoding.Unicode.GetBytes(password);
byte[] dst = new byte[bytes.Length];
byte[] inArray = HashAlgorithm.Create("SHA1").ComputeHash(dst);
return Convert.ToBase64String(inArray);
}
SHA1 is a hash algorithm, not an encryption algorithm. A hash algorithm is a one-way function which transforms data into a hash of that data, but the original data cannot be gotten back from the hash. An encryption algorithm is a two-way function which transforms data into encrypted data, and the encrypted data can then be transformed back into the original data.
To securely store a password so that it can be read back, use the ProtectedData class.
public static string ProtectPassword(string password)
{
byte[] bytes = Encoding.Unicode.GetBytes(password);
byte[] protectedPassword = ProtectedData.Protect(bytes, null, DataProtectionScope.CurrentUser);
return Convert.ToBase64String(protectedPassword);
}
public static string UnprotectPassword(string protectedPassword)
{
byte[] bytes = Convert.FromBase64String(protectedPassword);
byte[] password = ProtectedData.Unprotect(bytes, null, DataProtectionScope.CurrentUser);
return Encoding.Unicode.GetString(password);
}
Take whatever the user enters as a password to gain access to the system, encrypt it the same way and then compare the encrypted values, that's the normal approach. I'm pretty sure that SHA1 is a trapdoor encryption, i.e. can't be back-tracked.
You don't.
SHA1 is a hash, not encryption. It is a one-way operation; conversion back is not possible.
(Ok this is not strictly true; if you have a table of possible SHA1 values and plain text values, a rainbow table then you might be luck)
Also you should be salting your hashes, because you are, right now, vulnerable to rainbow table attacks. Jeff talks about this a little more on his blog
Okay, so I know this isn't answering your specific Q, but why do you want to convert it back?
If it's to compare in order to provide authentication, the standard approach is to encrypt this text ALSO, and compare the stored password to the supplied password.
This is more secure as it means that the original password never needs to be decrypted.
I think one of the points of using hashes is that they can't be computed back.
As someone else said, calculate the hash from the user's password and compare to the stored hash value.
In order to use the System.Security.Cryptography.ProtectedData class, you must add a reference to System.Security to your project.
(Right mouse click on the References folder, choose "Add Reference...", find System.Security on the .NET Tab)
Um, just curious but wouldn't that return the same hash for all passwords of the same length?
Using your own code snippet above, what you want to do is call that method when the user initially chooses a password - but add to the password what is called a salt somewhere in the password string (usually at the beginning or end). Then, when the user is attempting to authenticate later, they enter their password, you run that one along with the hash through this same method and if the two hashes are equal, it's a statistically excellent chance the passwords are equal and valid.
This being said, SHA1 is known to have weaknesses and you should choose a stronger algorithm. If you want to stay in the SHA family, SHA512 is pretty good.
You want to use encryption not hashing. SHA is fine but use the encryption methods for it. The problem with encryption is always where to put the key for it. You didn't mention whether this was a workstation or server you were doing this on. On a server, I find it better to just use ACL's to restrict access to the reg key. Admins can usually access the encryption key anyway...you have to have some trust somewhere. On a workstation then you can go with encryption and store the key in code or use a certificate and restrict access to it at least in a corp environment...not for sale software).
You can use the ProtectedData class but be aware that it uses user profiles for its key usage and as such you have to make sure you are impersonating the user who has the profile with the key you need. This may or may not be trivial and may or may not cause headaches and security issues.
I noticed the recent addition of the XMLEncryptedData class. For encrypting data to an XML file, is the XMLEncryptedData method more desirable than the DPAPI method?

Categories