Reputation: 54173
My web application logs into a web api. This needs an email and password. I cannot hash these in my database because the api requires the password in plain text.
How can I store my web api credentials in a safer way than plain text, xor, or base64? Is there a 'proper' solution for this sort of thing?
Upvotes: 1
Views: 2327
Reputation: 127603
Yes there is, the ProtectedData class, it lets you encrypt a object tied to a windows user acount, so if the user.config file is copied to another user/computer it will not work
In your Settings file, create two string properties named ApiUsername
and ApiPassword
, then click "View Code at the top and add the following functions
internal sealed partial class Settings {
private MD5 md5 = MD5.Create();
public global::System.Net.NetworkCredential ApiLogin
{
get
{
global::System.Net.NetworkCredential tmp = null;
if (ApiPassword != "")
{
tmp = new System.Net.NetworkCredential();
tmp.UserName = ApiUsername;
try
{
tmp.Password = System.Text.Encoding.UTF8.GetString(ProtectedData.Unprotect(Convert.FromBase64String(ApiPassword), md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(ApiUsername.ToUpper())), DataProtectionScope.CurrentUser));
}
catch
{
tmp.Password = "";
}
}
return tmp;
}
set
{
global::System.Net.NetworkCredential tmp2 = value;
ApiUsername = tmp2.UserName;
ApiPassword = Convert.ToBase64String(ProtectedData.Protect(System.Text.Encoding.UTF8.GetBytes(tmp2.Password), md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(tmp2.UserName.ToUpper())), DataProtectionScope.CurrentUser));
}
}
}
This will add a accessable property called ApiLogin
which will contain a NetworkCredential with the decrpted password, when you save the credentials to the disk it stores it in that encrpted protected form that can't be copied to other users.
If the decryption fails it sets the password to blank in the returned credential. If you want the decrption to work on any useraccount on that single machine change the ProtectionScope to DataProtectionScope.LocalMachine
.
Upvotes: 2