When i try login with correct username and password that is saved using hashing algorithm but there are some passwords saved as strings(not hashed). When i login using correct username and hashed password it works as expected but when i try to login using correct username and password(saved as string i.e not hashed) it gives an error stating Input string was not in a correct format and if password is saved as integer doesn't matter wrong or right(non hashed) it gives IndexOutOfRangeException: Index was outside the bounds of the array exception. although from now on i am hashing every password but for some of which is already created, i want to use them as well.
i don't know how to do that. this is the code where i get the error
var comparingPassword = PasswordHashManager.ValidatePassword(model.Password, correctPassword);
is there any way to check if password is hashed or not and if password is hashed then use comparingPassword otherwise use simple query to check login credentials.
Any decent password hash library has a function like VerifyPassword(userEnteredPassword, hashStoredInDb) and they require the user entered password together with the previously stored hash of the password. There is a huge security problem in your code, if the passwords are sometimes stored plaintext, and you should fix this instead of circumventing the problem.
Not sure what you mean with password saved as integer, but keep in mind that the function GetHashCode() is in no way a password hash function, instead use the CreateHash() of the password hash library, they are not compatible.
P.S. There are algorithms which are better suited for password hashing, like Argon2, BCrypt or SCrypt, so think about switching to another library.
Related
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.
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")
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;