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.
Related
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.
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
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 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.
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!