Currently I\'m writing it in clear text oops!, it\'s an in house program so it\'s not that bad but I\'d like to do it right. How should I go about encrypting this w
One option would be to store the hash (SHA1, MD5) of the password instead of the clear-text password, and whenever you want to see if the password is good, just compare it to that hash.
If you need secure storage (for example for a password that you will use to connect to a service), then the problem is more complicated.
If it is just for authentication, then it would be enough to use the hash.
Like ligget78 said, DPAPI would be a good way to go for storing passwords. Check out the ProtectedData class on MSDN for example usage.
Rather than encrypt/decrypt, you should be passing the password through a hashing algorithm, md5/sha512, or similar. What you would ideally do is hash the password and store the hash, then when the password is needed, you hash the entry and compare the entries. A password will then never be "decrypted", simply hashed and then compared.
This is what you would like to do:
OurKey.SetValue("Password", StringEncryptor.EncryptString(textBoxPassword.Text));
OurKey.GetValue("Password", StringEncryptor.DecryptString(textBoxPassword.Text));
You can do that with this the following classes. This class is a generic class is the client endpoint. It enables IOC of various encryption algorithms using Ninject.
public class StringEncryptor
{
private static IKernel _kernel;
static StringEncryptor()
{
_kernel = new StandardKernel(new EncryptionModule());
}
public static string EncryptString(string plainText)
{
return _kernel.Get<IStringEncryptor>().EncryptString(plainText);
}
public static string DecryptString(string encryptedText)
{
return _kernel.Get<IStringEncryptor>().DecryptString(encryptedText);
}
}
This next class is the ninject class that allows you to inject the various algorithms:
public class EncryptionModule : StandardModule
{
public override void Load()
{
Bind<IStringEncryptor>().To<TripleDESStringEncryptor>();
}
}
This is the interface that any algorithm needs to implement to encrypt/decrypt strings:
public interface IStringEncryptor
{
string EncryptString(string plainText);
string DecryptString(string encryptedText);
}
This is a implementation using the TripleDES algorithm:
public class TripleDESStringEncryptor : IStringEncryptor
{
private byte[] _key;
private byte[] _iv;
private TripleDESCryptoServiceProvider _provider;
public TripleDESStringEncryptor()
{
_key = System.Text.ASCIIEncoding.ASCII.GetBytes("GSYAHAGCBDUUADIADKOPAAAW");
_iv = System.Text.ASCIIEncoding.ASCII.GetBytes("USAZBGAW");
_provider = new TripleDESCryptoServiceProvider();
}
#region IStringEncryptor Members
public string EncryptString(string plainText)
{
return Transform(plainText, _provider.CreateEncryptor(_key, _iv));
}
public string DecryptString(string encryptedText)
{
return Transform(encryptedText, _provider.CreateDecryptor(_key, _iv));
}
#endregion
private string Transform(string text, ICryptoTransform transform)
{
if (text == null)
{
return null;
}
using (MemoryStream stream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(stream, transform, CryptoStreamMode.Write))
{
byte[] input = Encoding.Default.GetBytes(text);
cryptoStream.Write(input, 0, input.Length);
cryptoStream.FlushFinalBlock();
return Encoding.Default.GetString(stream.ToArray());
}
}
}
}
You can watch my video and download the code for this at : http://www.wrightin.gs/2008/11/how-to-encryptdecrypt-sensitive-column-contents-in-nhibernateactive-record-video.html
Tom Scott got it right in his coverage of how (not) to store passwords, on Computerphile.
https://www.youtube.com/watch?v=8ZtInClXe1Q
If you can at all avoid it, do not try to store passwords yourself. Use a separate, pre-established, trustworthy user authentication platform (e.g.: OAuth providers, you company's Active Directory domain, etc.) instead.
If you must store passwords, don't follow any of the guidance here. At least, not without also consulting more recent and reputable publications applicable to your language of choice.
There's certainly a lot of smart people here, and probably even some good guidance given. But the odds are strong that, by the time you read this, all of the answers here (including this one) will already be outdated.
All that said, here's some general guidance that will hopefully remain useful for awhile.
Process the passwords exactly as entered by the user during the creation process. Anything you do to the password before sending it to the cryptography module will probably just weaken it. Doing any of the following also just adds complexity to the password storage & verification process, which could cause other problems (perhaps even introduce vulnerabilities) down the road.
Reject creation of any passwords that can't be stored without modification. Reinforcing the above. If there's some reason your password storage mechanism can't appropriately handle certain characters, whitespaces, strings, or password lengths, then return an error and let the user know about the system's limitations so they can retry with a password that fits within them. For a better user experience, make a list of those limitations accessible to the user up-front. Don't even worry about, let alone bother, hiding the list from attackers - they'll figure it out easily enough on their own anyway.
Most importantly...
Go look up a reputable and very recent publication on the proper methods of password storage for your language of choice. Actually, you should find multiple recent publications from multiple separate sources that are in agreement before you settle on one method.
It's extremely possible that everything that everyone here (myself included) has said has already been superseded by better technologies or rendered insecure by newly developed attack methods. Go find something that's more probably not.
If you need more than this, for example securing a connection string (for connection to a database), check this article, as it provides the best "option" for this.
Oli's answer is also good, as it shows how you can create a hash for a string.