Adding unique salt to already hashed passwords in mysql - c#

I am trying to add unique salt to the hashed passwords in MySQL database. What is the most legitimate way of doing this? I am aware of that I need to hash them again to add a salt. These passwords are used for the website login. I can add one particular salt to each password before the code (written in C#) sends the user info to the database. In such a case, the login will work if I salt the passwords in MYSQL with the same salt. I know that it is not the most secure way. How do I implement the same with unique salts for each?

As the comments above state, you cannot reverse a hash, so you can't get the original password back to apply salt. You could apply salt to the hash string and hash again, but then you'd be stuck with that weird double-hash authentication method forever. Be sure to comment your code to explain why it is implemented this way, because programmers who take over your code when you leave will be confused.
I'll tell you how I did it when I was working on an app that needed to update its password-storage code from using MD5() to using salt + SHA1().
Leave the old hashed passwords alone.
Add a new column to the table storing your passwords for the new format of password. Call it password2 or something like that. This column is NULL by default.
Change the code to check the new column. If it is not NULL, then authenticate the user's input using the new hash method against what is stored in the database.
If the new column is NULL, then check against the old password using the old authentication method. I.e. hash the user's input and check that hash against what is stored in the database. Once you know the input is correct, hash the input again using the new method (add salt and hash the input, or better yet, use Bcrypt or Argon2 which contains its own salt in the hash result) and store that result in the new column.
Also set the old column to NULL after the new hash format is stored in the new column.
Of course the password-change code and new account creation code will also need to be changed. It should ignore the old password column, leaving it NULL, and only store passwords in the new format in the new column.
Once all users have logged in at least once, the old password column should be NULL on all rows. You can remove the application code that supported the old password hash format, and then drop the old password column.
But there will almost surely be some stragglers who don't log in regularly, so after a few weeks of waiting, I would just proceed to drop the old password. Those users who haven't logged in recently will be forced to do a password reset.
The advantage to this method is that it works totally seamlessly for nearly all your users, and inconveniences only a few (and some of those users may never return anyway).
The disadvantage is that it takes a few weeks to wait for everyone to log in once. If you need the change to occur immediately, then you may have to force all the users to do password reset.

Related

Generate password with specific salt

We are using Identity Server 4 for our user authentication.
I need to add a feature to restrict users from repeating one of their last 5 passwords.
To check the new password against their history, I think the best way is to (1 historic password at a time) use the historic salt to hash their new password, then compare the output.
I can get each historic salt from its hash, but I don't know how to
use a specific salt for the hash
generate the hash to compare against the historic one
I have checked the docs at http://docs.identityserver.io/en/release/ but I can't find anything relevent there.
Am I on the right track here? If so, how can I do the above? If not, how can I check that a new password hasn't been used before? (within the last 5 anyway)
IdentityServer4 does not do anything with user passwords or authentication. Are you asking about ASP.Net Identity? If so I'd suggest delving into the code for that in Github and overriding what you need.
As for a general approach; I'd use a hash salted with a user-specific, immutable salt but ONLY do that for historical passwords stored separately in a different table. Their current password should use a random salt as normal.

manage a secure password

My program asks for a password and save it inside a text file and the next time i run my program if the text file exists it asks for the password and I compare it with the password inside the text file.
Now, in the real world i know a text file is not used but I don't know how I can improve my technique 'cause regardless of a encryption algorithm a text file is readable for everyone and other solution as a registry key the same.
This is an exercise and my intention is to learn if I'm were programming a commercial app then what technique I should use to store a password with a more robust security?
It doesn't matter where you store your passwords, as long as you store only a hash of them. A text file will do pretty well, important is that you use a salt and a slow hash function with a cost factor. Algorithms like MD5 or SHA* are not appropriate to hash passwords, because they are too fast and therefore can be brute-forced too easily.
The library BCrypt.NET implements the BCrypt algorithm, which is designed to hash passwords. It will automatically add a cryptographically safe salt and includes it in the resulting BCrypt hash.
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
string hashToStoreInDb = BCrypt.HashPassword(password);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from existingHashFromDb.
bool isPasswordCorrect = BCrypt.Verify(password, existingHashFromDb);
Another good algorithm is PBKDF2, crackstation.net has a good code example.
If you are interested in more detailed information, you could have a look at my tutorial about safely storing passwords.
The idea is to encrypt or hash the password but never to decrypt it. I.e. you transform your password in a way which is not reversible.
When the password is entered the first time, you (one way) encrypt
the password and store it.
When a user tries to login, the entered password is encrypted again and compared with the stored one.
A code example was already provided in this answer:
byte[] data = System.Text.Encoding.ASCII.GetBytes(inputString);
data = new System.Security.Cryptography.SHA256Managed().ComputeHash(data);
String hash = System.Text.Encoding.ASCII.GetString(data);
Your program will store / compare the hash value instead of the plain password.
The code can and should be further approved. An attacker could create large dictionaries / rainbow tables of encrypted password and use them as a lookup for password cracking. This can be prevented by adding some "salt" to the password to be encrypted. Form more details see this answer.

Im making my first encryption program, any tips?

Im making a program in C# that has passwords and I need to encrypt them. So far I flip the string backwards (so hello becomes olleh) and then I use a loop that loops through each character, and the loop inside it loops through another string that has the converted letters to see if they match. Using this, hello = Ghh#$ so it works fine. So anyway, are there any extra stuff I can add to it? PS what is salting and how is hashing one way?
Rule one of cryptography is don't write your own encryption scheme. Instead use a library such as http://www.cryptlib.com/why-use-cryptlib-10-good-reasons which has bindings for C#.
For more information check out the first answer to:
https://security.stackexchange.com/questions/2202/lessons-learned-and-misconceptions-regarding-encryption-and-cryptology
First off, the difference between encryption and hashing is, at a high level, that encrypted data can be decrypted with the right key, whereas hashed data cannot be retrieved except via brute force methods like pregeneration or rainbow tables.
Hashed passwords are validated by hashing the user's input each time that they log in in the same way that you do when they create the account, and comparing the result of the hash. For any given input, the hashed result should be the same.
Obligatory rant:
There is a good argument to be made that passwords should always be hashed using a cryptographically-strong algorithm. You may hear the excuse that "my application/web page/etc is not all that important, there is no sensitive information there", or "I'm just learning so it isn't important", but the fact is that if I can crack the security of one website, or you leave your machine logged in and I steal your password file from your "educational" app, I can take all of the user's email addresses and virtually guarantee that at least a few of them will use the same password for that gmail or yahoo account. I can then send reset requests for just about any site that their email tells me they have an account for and get access to those also. So it is very important that no matter what software you are writing, if it stores passwords, you should do the responsible thing and salt + hash them properly.
Salt: http://en.wikipedia.org/wiki/Salt_(cryptography)
Hashing: http://en.wikipedia.org/wiki/Cryptographic_hash_function
Simplistic Example:
var salt = "abc123";
var encryptedPassword = HashingAlgorithm("password");
var encryptedSaltedPassword = HashingAlgorithm ("password" + salt);
Console.Writeline(encryptedPassword);
Console.Writeline(encryptedSaltedPassword);
writes out
aIdekXieklKq309nasdf
dfk#cxk)8lkdfesijcde
The point of salting your code is to prevent dictionary attacks. If anyone figures out your HashingAlgorithm, they can brute-force run through every word in the dictionary and figure out that "password" hashes to be "aIdekXieklKq309nasdf". If you salt your to-be-encrypted words, they'd have to know your salt word too.
Also, it's good to hash your passwords into a database instead of using some two-way algorithm, that way anyone (including you and your co-workers) having access to the database can look and see what your users use as passwords (since a lot of users tend to reuse the same passwords on multiple sites).

What is the best way to encrypt a password?

I am about to make a 'Log In' for my app and was wondering what is the best way to encrypt a password for my user that i will enter in my database ? I found many way on Google but don't know which is the best.
I would go with a one way salted hash.
Using a SHA1 hash for example, you would have a way to store the password as a hash which cannot be reversed back to the original password. Then when the user enters his/her password you perform the same SHA1 hash on the password and compare that hash with what you have stored in the DB, if they match then the password is correct.
To further secure the hashing, you can add a salt, this is essentially a randomly generated value that you generate for each user then you create the account, and store the salt value in the user record. When you create the hash of the password, you first combine the password with the salt and hash this combined value. To authenticate the user you combine the entered password with the salt stored for the user, perform the hash on the combined value and compare.
By adding the salt to the mix, you ensure that the hash for passwords that happend to be the same have a different hash because the salted portion differs. So if two users have the same password "Password1234", the stored hash for the two will not be the same so it cannot be determined that two users have the same password.
I recommend using Rfc2898DeriveBytes
It uses a good standardized Key-Derivation-Function, and modern hashes. You need to pass in a salt in addition to the password to prevent rainbow-tables. And it mixes salt and password for you, so you don't need to figure out how to do that yourself.
Use bcrypt. No, really, drop whatever ideas you have of building your own method, and use bcrypt. The world has enough homebrew insecure password hashing schemes already.
Storing salted password hashes, with per-user salts of course, is all well and good. But salting only prevents rainbow table attacks, it doesn't prevent bruteforcing. So, paradoxically, you don't want to use a fast method to generate or verify the password hashes. MD5, SHA, whatever - they're all fast. Repeat after me: use bcrypt.
You can use RSA Algorithm: http://www.codeproject.com/KB/security/RSACryptoPad.aspx
Use Cryptography algorithm provided by .net framework
normally , many application uses MD5 algorithem
See here

How to encrypt a password for saving it later in a database or text file?

I want my application to save the password encrypted in a database or in a text file.
How can I do that assuming that the database or text file can be open by anyone?
Duplicate
Encrypting/Hashing plain text passwords in database
Not duplicate
I'm asking for code specific for .NET
EDIT: I'm saving the password for later use. I need to decode it and use it to login.
It doesn't have to be super secure, it just needs to be unreadable to the human eye, and difficult to decode with a trivial script.
StackOverflow readers don't know how to write secure password schemes and neither do you. If you're going to do that, save time by sticking with plain text. From Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes:
Rainbow tables are easy to beat. For
each password, generate a random
number (a nonce). Hash the password
with the nonce, and store both the
hash and the nonce. The server has
enough information to verify passwords
(the nonce is stored in the clear).
But even with a small random value,
say, 16 bits, rainbow tables are
infeasible: there are now 65,536
“variants” of each hash, and instead
of 300 billion rainbow table entries,
you need quadrillions. The nonce in
this scheme is called a “salt”.
Cool, huh? Yeah, and Unix crypt —-
almost the lowest common denominator
in security systems —- has had this
feature since 1976. If this is news to
you, you shouldn’t be designing
password systems. Use someone else’s
good one.
Use BCrypt - Strong Password Hashing for .NET and Mono. It's a single cleanly written .cs file that will continue to meet your needs as password cracking computers get faster.
BCrypt - Strong Password Hashing for .NET and Mono
Triple DES is one way to do it, as long as you mean "A password that my system needs to be able to recall in order to access a resource". If you mean the password is something a user needs to be able to gain access to your system, probably don't want encryption, just a hash will do. When you store the hashed password value, it is useless to anyone with direct database access, but can still be used for authentication. All you do is compare the stored hash against a hash of the incoming password. If they match, then you grant access.
It isn't perfect, by any means, but it is the way 99.999% of people store their passwords.
If you want to argue that you wish to provide the password back to a user if they lose/forget it, then please don't. Issue them with a temporary password (which you store hashed in the db) and get them to change it on first login.
Use Data Protection API either with the user or machine store (e.g. different key per account your program/database server runs under vs. one key per machine). This will help you decode the passwords later and you don't have to remember or store any encryption keys. The downside of it is that when you reinstall the system/delete the account you won't be able to recover the data, I believe.
If you use encryption for securely storing passwords, you'll need to store the encryption "key" somewhere, too. This will be the "weak link", since if someone gets hold of the encryption key, they will be able to decrypt the encrypted passwords.
Since this is passwords that we're talking about here, a much better solution is to use a one-way hash. You hash the password when the user first creates it (preferably hashing with a salt value) and store the resulting hash value. Since hashes are one-way, no one can reverse the hash to the original plain text value.
To check that a users password is correct, you simply ask the user for the plain-text password, hash their input again and compare the resulting hash value with the hash value you have stored (taking salts into account of course). If the two hash values are the same, the user has entered the correct password.
Please see the following links for further info:
Hashing Password with Salt
For encryption (if you need to use that), I'd use Rijndael (AES).
Based on your question I can see two approaches depending on why you are storing the password.
A. if you only need to authenticate using their password and nothing else.
In that case, going using an algorithm that is not reversible (Hashing) would be your best choice. You will need to make sure of a couple of things:
Make sure that the connection is encrypted when transmitting the password from the client to the server. This will prevent it from being sniffed out. This is pretty trivial to do with web applications since the web server is doing the heavy lifting for you. If not it gets a lot tricker and is the subject of an whole other question.
Choose a solid hashing algorithm to prevent collision. I would recommend SHA-256 even if it does provide a larger result than SHA1 or MD5. The reference from Microsoft on using their implementation of the algorythm is here.
Salt the password to prevent attacks using rainbowtable (i.e. looking up the password in large table with the precomputed hash and the associated password in clear text). The answer here (sited in your question) gives good pseudo code in Python on how to do it. There is also a good example of .NET code here.
B. if you need to be able to read the password for each user for other purposes than authenticating the user.
This case is easy if we are only talking about storing a password (or any kind of sensitive information) on a single computer (server). If that's the case, using the Microsoft Data Protection API would be a good solution since it is tied to that computer and (depending on the way you work) the user under which you application runs and takes care of the worst of the job for you (creating, storing, and using keys). You can find some code reference from Microsoft here. If you need it on more than one system and are not willing to enter the password on each system you install on your application then things get a lot more complex because you need to implement a lot of it from scratch. That would be the subject for another question I would think.
If you need to decrypt the password for later use and it doesn't have to be SUPER secure, then use the method here:
http://support.microsoft.com/kb/307010
It's well documented, and easy to understand.
do you need to encrypt it ever again? otherwise use a hashfunction to encrypt it and encrypt the password given by the user with the same hashfunction and look if the hashes are equal.
The reason for not using a 2-way-encryption is that one cannot decrypt your key - since a good hashfunction has collisions.
Personally, I would use something that has one-way encryption - MD5, SHA1, etc...
You can use the FormsAuthentication class with it's HashPasswordForStoringInConfigFile method. When validating the user, encrypt the entered password and compare it with the stored version.
Like ocdecio I would use TripleDes, I would also save the salt in the database too. The key for me is usually hard coded, but the salt should change for each encrypted item.
If you just need the password for an internal authentication process, you should not save the actual password, but save a hash of this password. When you need to check if a password is valid, you'll have to run the hash function on provided password and compare it with the hash you stored in your database/file. You can never find the original password from the hash.
If you need to keep the original password, you'll have to encrypt it. You can use for example a public key infrastructure if you have a process that writes the passwords (public key) and another one that reads them (private key).
Do you really need to be able to retrieve the password itself? If you're storing a password for the purposes of authenticating someone (or something), you should rather hash it (with salting) and then compare that hash to the hash of the password supplied by the party wishing to be authenticated.
If, on the other hand, you need to store the password in order to be able to retrieve it and supply it to some other authentication service later, then you might want to store it encrypted. In that case, use any decent symmetrical encryption algorithm you can, such as TripleDES or AES or Blowfish.
Briefly:
Get a big random number which you will keep private and only your application code will have access to.
Encrypt the password + random number with an ancryption algorithm like SHA1, most programming languages have a cryptography framework.
Store the hashed password.
Later when you want to check inputted passwords, you can rehash the user input and compare to the "virtually" undecipherable stored passwords.
Here's a string encryption article with example code .NET
http://www.devarticles.com/c/a/VB.Net/String-Encryption-With-Visual-Basic-.NET/3/
There is no need to use anything fancy, because anyone with a little bit of skill and determination will break it anyway.

Categories