28 sept 2016

Calcular un hash MD5 y devolverlo en formato leíble

El uso de hashes es bastante común en programación, se puede utilizar para guardar una contraseña, (en este caso ya no es recomendable recurrir al MD5), se puede usar para guardar una cadena de verificación o firma e incluso para comparar archivos.

El framework .Net nos presenta una gran variedad de herramientas para calcular un hash, en este caso usaremos la clase MD5CryptoServiceProvider del namespace using System.Security.Cryptography.

Una duda que muchas veces aparece al intentar usar estos CryptoServiceProviders es cómo mostrar el hash para que sea leíble, ya que la función que utilizamos nos devuelveun Array de bytes.

Pues eso es sencillo, recurrimos a la función ToString() y como argumento pasamos "x2" con lo que por cada ítem del array obtendremos un valor hexadecimal de 2 dígitos.

Entonces la función se vería así:

public string MD5Hash(string texto)
{
 var resultado = new StringBuilder();
 using (var md5 = new MD5CryptoServiceProvider())
 {
  var hash = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(texto);
  foreach (byte b in hash)
  {
   resultado.Append(b.ToString("x2"));
  }
 }
 return resultado.ToString();
}

2 jun 2016

Password prompt en aplicación de consola de .Net

Muchas veces utilizo aplicaciones de consola, principalmente cuando desarrollo un cliente para alguna API y necesito crear una aplicación de test para mi librería... pero algo que siempre me molestó es no poder enmascarar el password mientras se lo ingresa en la consola... así fue que un día decidí investigar y me encontré con una solución que tenía algunas fallas y le faltaba trabajo... pero recuerdo que lo tomé como base y luego de una buena edición lo uso en todos mis proyectos de aplicación de consola en los que se ingresa un password.

Creo que una de las formas más seguras de enmascarar un password es el que se usa en GNU/Linux, no mostrar nada al ingresar el password, de esa forma no sólo se ocultan los caracteres que conforman el password, pero también se oculta el largo de la cadena, pero hay quienes prefieren ver un asterisco por cada caracter, así que eso es configurable.



Veamos la función que lee y devuelve el password:

static string LeerPassword()
{
    // Caracter a mostrar en pantalla 
    const string mascara = "*";

    ConsoleKeyInfo key;
    var passwd = string.Empty;
    do
    {
        // Leer una tecla a la vez
        key = Console.ReadKey(true);

        if (key.Key != ConsoleKey.Backspace && key.Key != ConsoleKey.Enter)
        {
            // Agrego el caracter a la cadena
            passwd += key.KeyChar;
            Console.Write(mascara);
        }
        else if (key.Key == ConsoleKey.Backspace)
        {
            if (mascara.Length > 0)
            {
                // Si la máscara se imprime hay que borrarla
                Console.Write("\b \b");
            }
            if (!string.IsNullOrEmpty(passwd))
            {
                // Quitar el último caracter de la cadena
                passwd = passwd.Substring(0, passwd.Length - 1);
            }
        }
    }
    while (key.Key != ConsoleKey.Enter);

    return passwd;
}


Con esta simple función ya tenemos esta funcionalidad implementada, resta invocarla desde el punto donde queremos leer el password y listo!

static void Main(string[] args)
{
    Console.Clear();

    Console.WriteLine("Aprendiendo.Net - Enmascarar password");
    Console.WriteLine();
    Console.Write("Usuario: ");
    var usuario = Console.ReadLine();
    Console.Write("Password: ");
    var passwd = LeerPassword();

    /*
     * Validación y resto del código
     */

    Console.ReadLine();
}


Modificando el valor de la constante mascara en nuestra función LeerCodigo() podremos variar el caracter que se mostrará en pantalla al ingresar el password, incluso podemos usar un string vacío para lograr el efecto que nombraba respecto a las aplicaciones en GNU/Linux.