I have a desktop application with a remote interface. The access to the remote interface is secured by a username and password.
What would be the best way to save these password securely, preferably in the registry?
I have a desktop application with a remote interface. The access to the remote interface is secured by a username and password.
What would be the best way to save these password securely, preferably in the registry?
You would need to save the hashed password (be it in the registry or somewhere else). Then when the user enters their password you check the hashed version of what they enter with the hashed version as stored. If these match then the passwords match and you can let the user in.
This way you're not storing the password in plain text for anyone (including yourself) to get at and gain access as someone else.
As to which hash algorithm to use - I don't know. There are plenty to choose from, so I'm reluctant to recommend one blind. I'd suggest you find several and evaluate them. CSharpFriends has an article which looks like it might be a good starting point.
If you do need to store an unhashed password, look at using the ProtectedData class. This makes use of the Data Protection API (DPAPI) which is the best way of securing data on Windows.
Here's a little class that wraps ProtectedData and provides two extension methods on String to Encrypt and Decrypt data:
public static class DataProtectionApiWrapper
{
/// <summary>
/// Specifies the data protection scope of the DPAPI.
/// </summary>
private const DataProtectionScope Scope = DataProtectionScope.CurrentUser;
public static string Encrypt(this string text)
{
if (text == null)
{
throw new ArgumentNullException("text");
}
//encrypt data
var data = Encoding.Unicode.GetBytes(text);
byte[] encrypted = ProtectedData.Protect(data, null, Scope);
//return as base64 string
return Convert.ToBase64String(encrypted);
}
public static string Decrypt(this string cipher)
{
if (cipher == null)
{
throw new ArgumentNullException("cipher");
}
//parse base64 string
byte[] data = Convert.FromBase64String(cipher);
//decrypt data
byte[] decrypted = ProtectedData.Unprotect(data, null, Scope);
return Encoding.Unicode.GetString(decrypted);
}
}