c# - Usando SecureString
security (8)
¿Puede esto simplificarse a un trazador de líneas uno? Siéntase libre de reescribirlo por completo siempre que secureString se inicialice correctamente.
SecureString secureString = new SecureString ();
foreach (char c in "fizzbuzz".ToCharArray())
{
secureString.AppendChar (c);
}
Además de usar código inseguro y un char*
, no hay una (mucho) mejor forma.
El punto aquí no es copiar los contenidos de SecureString a / desde cadenas normales. La constante constante "fizzbuzz"
es la fuga de seguridad aquí.
Aquí hay una clase NetworkCredential de .NET haciéndolo:
SecureString secureString;
fixed (char* chPtr = plainString)
secureString = new SecureString(chPtr, plainString.Length);
Feo, pero probablemente el más eficiente.
Dado que SecureString
utiliza la interfaz IDispose
. En realidad podrías hacerlo así.
SecureString secure = new SecureString();
foreach(var character in data.ToCharArray())
secure.AppendChar(character);
Esencialmente, los data
serían un parámetro.
Si utiliza el using
para ayudar a aliviar los recursos; querrás tener cuidado con el alcance. Pero esta puede ser una alternativa beneficiosa, dependiendo del uso.
Actualizar:
En realidad podría hacer una firma de método completo:
public static SecureString ConvertStringToSecureString(this string data)
{
var secure = new SecureString()
foreach(var character in data.ToCharArray())
secure.AppendChar(character);
secure.MakeReadOnly();
return secure;
}
Para el descifrado que desearía hacer:
public static string ConvertSecureStringToString(this SecureString data)
{
var pointer = IntPtr.Zero;
try
{
pointer = Marshal.SecureStringToGlobalAllocUnicode(data);
return Marshal.PtrToStringUni(pointer);
}
finally
{
Marshal.ZeroFreeGlobalAllocUnicode(pointer);
}
}
El siguiente article le dará información adicional.
Leve mejora en la respuesta de Sascha reemplazando la lambda con un grupo de métodos
"fizzbuzz".ToCharArray().ToList().ForEach(ss.AppendChar);
Puedes usar Linq:
"fizzbuzz".ToCharArray ().ToList ().ForEach ( p => secureString.AppendChar ( p ) );
Solo use NetworkCredential. Tiene la lógica de conversión incorporada.
SecureString ss = new NetworkCredential("", "fizzbuzz").SecurePassword;
Como han señalado otros, todas estas técnicas eliminan los beneficios de seguridad de SecureString, pero en ciertas situaciones (como pruebas unitarias) esto puede ser aceptable.
Actualizar:
Como se señala en los comentarios, NetworkCredential también se puede usar para convertir un SecureString en una cadena.
string s = new NetworkCredential("", ss).Password;
menos cantidad de código porque .ToList()
no es necesario para esto:
Array.ForEach("fizzbuzz".ToCharArray(), secureString.AppendChar);
var s = "fizzbuzz".Aggregate(new SecureString(), (ss, c) => { ss.AppendChar(c); return ss; });