simple encrypt decrypt crypto computehash code and c# encryption

c# - encrypt - Cómo almacenar correctamente la contraseña localmente



encrypt md5 c# (3)

He estado leyendo este artículo de MSDN en Rfc2898DeriveBytes . Aquí está el código de encriptación de muestra que proporcionan.

string pwd1 = passwordargs[0]; // Create a byte array to hold the random value. byte[] salt1 = new byte[8]; using (RNGCryptoServiceProvider rngCsp = ne RNGCryptoServiceProvider()) { // Fill the array with a random value. rngCsp.GetBytes(salt1); } //data1 can be a string or contents of a file. string data1 = "Some test data"; //The default iteration count is 1000 so the two methods use the same iteration count. int myIterations = 1000; try { Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(pwd1,salt1,myIterations); Rfc2898DeriveBytes k2 = new Rfc2898DeriveBytes(pwd1, salt1); // Encrypt the data. TripleDES encAlg = TripleDES.Create(); encAlg.Key = k1.GetBytes(16); MemoryStream encryptionStream = new MemoryStream(); CryptoStream encrypt = newCryptoStream(encryptionStream, encAlg.CreateEncryptor(), CryptoStreamMode.Write); byte[] utfD1 = new System.Text.UTF8Encoding(false).GetBytes(data1); encrypt.Write(utfD1, 0, utfD1.Length); encrypt.FlushFinalBlock(); encrypt.Close(); byte[] edata1 = encryptionStream.ToArray(); k1.Reset();

Mi pregunta es, ¿cómo podría leer / escribir correctamente los datos hash a / desde un archivo de texto?

Mi objetivo principal es hacer lo que hace este desarrollador . Necesito almacenar una contraseña localmente. Cuando mi aplicación solicita al usuario la contraseña, el usuario ingresará la contraseña, luego mi aplicación leerá el archivo de texto y verificará si la contraseña que ingresó es correcta. ¿Cómo podría hacerlo?


Cómo almacenar correctamente la contraseña localmente

Simplemente no lo hagas. No, realmente no lo hagas .

... Pero si realmente tienes que hacerlo, nunca lo implementes tú solo. Yo recomendaría revisar cómo ASP.NET Identity hash contraseñas . La versión 3 es bastante sólida en este momento:

tenga en cuenta que lo siguiente está tomado de github.com y puede cambiarse en cualquier momento. Para lo último, consulte el enlace anterior.

private static byte[] HashPasswordV3(string password, RandomNumberGenerator rng, KeyDerivationPrf prf, int iterCount, int saltSize, int numBytesRequested) { // Produce a version 3 (see comment above) text hash. byte[] salt = new byte[saltSize]; rng.GetBytes(salt); byte[] subkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, numBytesRequested); var outputBytes = new byte[13 + salt.Length + subkey.Length]; outputBytes[0] = 0x01; // format marker WriteNetworkByteOrder(outputBytes, 1, (uint)prf); WriteNetworkByteOrder(outputBytes, 5, (uint)iterCount); WriteNetworkByteOrder(outputBytes, 9, (uint)saltSize); Buffer.BlockCopy(salt, 0, outputBytes, 13, salt.Length); Buffer.BlockCopy(subkey, 0, outputBytes, 13 + saltSize, subkey.Length); return outputBytes; }


Debe almacenar la contraseña como un hash de un sentido y la sal utilizada para crear esa contraseña. De esta forma, está absolutamente seguro de que la contraseña del usuario nunca podrá ser DESCRITADA. Nunca utilice ningún cifrado bidireccional para esta tarea en particular, ya que corre el riesgo de exponer la información del usuario a posibles atacantes.

void Main() { string phrase, salt, result; phrase = "test"; result = Sha256Hash(phrase, out salt); Sha256Compare(phrase, result, salt); } public string Sha256Hash(string phrase, out string salt) { salt = Create256BitSalt(); string saltAndPwd = String.Concat(phrase, salt); Encoding encoder = Encoding.Default; SHA256Managed sha256hasher = new SHA256Managed(); byte[] hashedDataBytes = sha256hasher.ComputeHash(encoder.GetBytes(saltAndPwd)); string hashedPwd = Encoding.Default.GetString(hashedDataBytes); return hashedPwd; } public bool Sha256Compare(string phrase, string hash, string salt) { string saltAndPwd = String.Concat(phrase, salt); Encoding encoder = Encoding.Default; SHA256Managed sha256hasher = new SHA256Managed(); byte[] hashedDataBytes = sha256hasher.ComputeHash(encoder.GetBytes(saltAndPwd)); string hashedPwd = Encoding.Default.GetString(hashedDataBytes); return string.Compare(hash, hashedPwd, false) == 0; } public string Create256BitSalt() { int _saltSize = 32; byte[] ba = new byte[_saltSize]; RNGCryptoServiceProvider.Create().GetBytes(ba); return Encoding.Default.GetString(ba); }

También podría encontrar otro método para obtener la sal, pero yo he calculado que calcula 2048 bits de datos aleatorios. Podrías usar una longitud aleatoria que generas pero que sería mucho menos segura. No podrá usar SecureString porque SecureString no se puede serializar. Cuál es el objetivo de DPAPI. Hay formas de sacar los datos, pero terminas teniendo que saltar algunos obstáculos para hacerlo.

FWIW, PBKDF2 (función de derivación de clave basada en contraseña 2) es básicamente lo mismo que SHA256, excepto más lento (algo bueno). Por sí solo, ambos son muy seguros. Si combinaste PBKDF2 con un SHA256 como tu sal, tendrías un sistema muy seguro.


Normalmente almacena el hash de la contraseña, luego cuando el usuario ingresa la contraseña, calcula el hash sobre la contraseña ingresada y lo compara con el hash que se almacenó; dicho esto, el hash no es suficiente (desde el punto de vista de la seguridad) y usted debería usar una función como PKBDF2 (función de derivación de clave basada en contraseña 2). Aquí está el artículo que cubre toda esa información de una manera más elaborada, así como el código de muestra (parte inferior de la página): http://www.codeproject.com/Articles/704865/Salted-Password-Hashing-Doing-it-Right

Aquí hay un enlace a la revisión del código , que supongo se refiere a la misma implementación que el artículo anterior.