【发布时间】:2011-01-17 10:13:57
【问题描述】:
我有一个程序,它使用System.DirectoryServices.AccountManagement.PrincipalContext 来验证用户在设置屏幕中输入的信息是否是域中的有效用户(计算机本身不在域中)并对领域。问题是我不希望用户在每次运行程序时都需要输入他或她的密码,所以我想保存它,但我不喜欢将密码以纯文本形式存储在他们的 app.config 文件中。 PrincipalContext 需要一个纯文本密码,所以我不能像每个人都建议的那样进行加盐哈希来存储密码。
这就是我所做的
const byte[] mySalt = //It's a secret to everybody.
[global::System.Configuration.UserScopedSettingAttribute()]
public global::System.Net.NetworkCredential ServerLogin
{
get
{
var tmp = ((global::System.Net.NetworkCredential)(this["ServerLogin"]));
if(tmp != null)
tmp.Password = new System.Text.ASCIIEncoding().GetString(ProtectedData.Unprotect(Convert.FromBase64String(tmp.Password), mySalt, DataProtectionScope.CurrentUser));
return tmp;
}
set
{
var tmp = value;
tmp.Password = Convert.ToBase64String(ProtectedData.Protect(new System.Text.ASCIIEncoding().GetBytes(tmp.Password), mySalt, DataProtectionScope.CurrentUser));
this["ServerLogin"] = value;
}
}
这是正确的做法还是有更好的方法?
编辑—— 这是根据大家的建议更新的版本
private MD5 md5 = MD5.Create();
[global::System.Configuration.UserScopedSettingAttribute()]
public global::System.Net.NetworkCredential ServerLogin
{
get
{
var tmp = ((global::System.Net.NetworkCredential)(this["ServerLogin"]));
if(tmp != null)
tmp.Password = System.Text.Encoding.UTF8.GetString(ProtectedData.Unprotect(Convert.FromBase64String(tmp.Password), md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(tmp.UserName.ToUpper())), DataProtectionScope.CurrentUser));
return tmp;
}
set
{
var tmp = value;
tmp.Password = Convert.ToBase64String(ProtectedData.Protect(System.Text.Encoding.UTF8.GetBytes(tmp.Password), md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(tmp.UserName.ToUpper())), DataProtectionScope.CurrentUser));
this["ServerLogin"] = tmp;
}
}
【问题讨论】:
-
你想保护谁和什么密码?
-
我会说“正确”的方式是保留 Kerberos 票证,但我不知道在这种情况下如何处理,抱歉。
-
@Slaks - 我正在为那些坐在别人电脑前的无聊同事保护密码。我只想保护不经意的观察者,而不是坚定的黑客。
标签: c# encryption passwords