Tengo un programa que usa System.DirectoryServices.AccountManagement.PrincipalContext
para verificar que la información que un usuario ingresó en una pantalla de configuración es un usuario válido en el dominio (la computadora no está en el dominio) y hacer algunas operaciones en los usuarios del dominio. El problema es que no quiero que el usuario tenga que ingresar su contraseña cada vez que ejecuta el programa, así que quiero guardarlo, pero no me siento cómodo almacenando la contraseña como texto sin formato en su archivo app.config. PrincipalContext necesita una contraseña de texto sin formato, por lo que no puedo hacer un hash salado ya que todo el mundo lo recomienda para el almacenamiento de contraseñas.Qué hacer cuando no puede guardar una contraseña como hash
Esto es lo que hice
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;
}
}
¿Era esto lo que hay que hacer o hay una manera mejor?
EDITAR - Aquí está una versión actualizada en base a las sugerencias de todos
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;
}
}
¿Quién y qué está tratando de defender la contraseña? – SLaks
Diría que la forma "adecuada" sería mantener el boleto Kerberos, pero no sé cómo en este contexto, lo siento. – ziya
@Slaks - Estoy defendiendo la contraseña de compañeros de trabajo aburridos que se han sentado en la computadora de otra persona. Solo quiero protegerme del observador casual, no de un hacker determinado. –