Verifying Passwords via Hascode - c#

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")

Related

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.

Encryption Comparing Hashed&Salted Password upon Login

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.

How to validate a user in asp.net web site using the existing encrypted password stored in the SQL Database?

Hi i am using the MD5 encyrption in my asp.net website where it stores the passwords to the database using the MD5 encryption.so when i want to login using the credentials entered during the registration of the user i am having trouble comparing the existing password from the database to the current one which i entered to login.As the stored password is in the ecrypted form i am confused how to compare the encrypted format to the text format ?
I am using the Sqlserver as my database.
In addition to what #Jason said... I like salting the password.
public static string CreateSalt(int byteSize)
{
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] buff = new byte[byteSize];
rng.GetBytes(buff);
return Convert.ToBase64String(buff);
}
public static string CreatePasswordHash(string pwd, string salt)
{
string saltAndPwd = String.Concat(pwd, salt);
string hashedPwd = FormsAuthentication.HashPasswordForStoringInConfigFile(saltAndPwd, "sha1");
return hashedPwd;
}
when the user is intially created, here is the process
Create the salt => CreateSalt(16)
Create the hash with the password and salt => CreatePasswordHash(passwordEntered, salt)
Store the hashed password and salt
next time the user logs in, validate the stored credentials against what they have entered into the login form
=> string enteredPasswordHash = CreatePasswordHash(enteredPassword, saltFromDatabase)
the compare against what is in the database
=> if(passwordHashInDatabase != enteredPasswordHash) => wrong login credentials
Hope this helps someone...
MD5 is a one way hash, so the password in the database cannot be converted back to plain text. Instead you have to convert the plain text password (the one entered in the login form) to cypher text using the MD5 hash algorithm.
To compare the MD5 hashes you would need to query the database based on the User Name enter in the login and return the known MD5 hash and the salt (if there is one). Then hash the given password with the known salt. You can then compare the two hashes for a match.
If you are definitely storing the password in an encrypted state, then you only need to encrypt their plaintext password (using the same key) and compare it to the database value. Apples to apples. When encrypted using the same key and algorithm, it will always encrypt and decrypt to the same value.
If this doesn't appear to be working correctly, I would guess that you are not using the same key that you used when you first stored the value in the database. Double-check and make sure that the key you encrypt with is exactly the same as the key you decrypt with. Typically, many of us will use a machine or user-level certificate as a key, to ensure that the value isn't tampered with or changed.
If (instead) you are using MD5 to hash the password, then it's not actually encrypted. Hashing totally munges the plaintext value and you will never get it back. It's the safest and smartest way to store passwords. You merely hash the plaintext into an encoded value and save it to the database -- then, you compare against that hashed value any time the user logs in.
I'm hoping you are hashing and not encrypting. It's definitely a best practice when it comes to password storage. It's very easy to implement and will save you headaches if you're ever audited.
Good luck!

Password encryption

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;

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