Archivo de la etiqueta: tutorial

Generar clave SHA1 con el nombre y password del usuario

Pues eso… en este post te explico cómo generar una clave (usando la clase SHA1CryptoServiceProvider) formada a partir de dos cadenas, normalmente el nombre del usuario y el password (o contraseña), de esta forma se genera una cadena única (de 40 caracteres) de forma que si alguien accede a ella no sabrá nunca cuales fueron las dos cadenas que la formaron (o eso es lo que espero que ocurra, jejeje). Además te mostraré también una función para evitar que el usuario introduzca caracteres no válidos y que pueden se usados para acceder maliciosamente a una base de datos.
Por supuesto, te mostraré el código tanto para Visual Basic como para C#.

El código que te mostraré (al menos el de generar la clave SHA1) está basado en este código publicado en mi sitio (usando .NET 1.1):
El ejemplo de Visual Basic .NET:
comprobar_usuario_usando_base_datos_vb2003
El ejemplo de C#:
comprobar_usuario_usando_base_datos_cs2003

Generar una clave SHA1 usando SHA1CryptoServiceProvider

Para acceder a esta clase necesitas una importación del espacio de nombres System.Security.Cryptography y como en el código usaremos un objeto StringBuilder y UTF8Encoding, también habrá que importar System.Text.

En el código de ejemplo para usar los métodos definidos en la clase UtilSHA1 (que será en la que defino los dos métodos usados) se hará una comprobación de si tanto en el nombre como en el password usado hay caracteres no válidos, los caracteres que compruebo en el método ValidarTextoClave son los caracteres: ?*%’_ y

De esa forma intentamos asegurarnos que no se pueda hacer un SQL injection, es decir, intentar acceder maliciosamente a la base de datos a la que presumiblemente se quiere acceder.

Veamos primero el código que usa los dos métodos, el de comprobar la validez del texto introducido (ValidarTextoClave) y el de generar la clave SHA1 (GenerarClaveSHA1).

Método Main con el código de prueba para usar los métodos de la clase

Como te dije antes, se pide el nombre del usuario y el password a usar para generar la cadena con la clave SHA1 (que será de 40 caracteres convertidos a mayúsculas).

Este sería el código del método Main para Visual Basic, con las importaciones de los espacios de nombres necesarios en todo el código de ejemplo:

Option Strict On
Option Infer On

Imports System

Imports System.Text
Imports System.Security.Cryptography

Module Program
    Sub Main(args As String())
        
        dim valido As Boolean
        dim usuario As String
        dim passw as String

        Do
            Console.Write("Escribe el nombre del usuario: ")
            usuario = Console.ReadLine()
            ' si el nombre del usuario tiene caracteres no permitidos, preguntar de nuevo
            valido = UtilSHA1.ValidarTextoClave(usuario)
            if not valido
                Console.WriteLine("Nombre de usuario NO VÁLIDO.")
            end if
        Loop While Not valido

        Do
            Console.Write("Escribe la clave: ")
            passw = Console.ReadLine()
            ' si la clave tiene caracteres no permitidos, preguntar de nuevo
            valido = UtilSHA1.ValidarTextoClave(passw)
            if not valido
                Console.WriteLine("La clave NO ES VÁLIDA.")
            end if
        Loop While Not valido

        ' generar la clave SHA1 y mostrarla
        dim claveSHA1 = UtilSHA1.GenerarClaveSHA1(usuario, passw)
        Console.WriteLine($"La clave SHA1 es: '{claveSHA1}'.")
            
    End Sub
End Module

 

Este sería el código del método Main para C#, con las importaciones (using) de los espacios de nombres usados en el código:

using System;

using System.Text;
using System.Security.Cryptography;

class Program
{
    static void Main(string[] args)
    {
        bool valido;
        string usuario;
        string passw;

        do
        {
            Console.Write("Escribe el nombre del usuario: ");
            usuario = Console.ReadLine();
            // si el nombre del usuario tiene caracteres no permitidos, preguntar de nuevo
            valido = UtilSHA1.ValidarTextoClave(usuario);
            if (!valido)
                Console.WriteLine("Nombre de usuario NO VÁLIDO.");
        }
        while (!valido);

        do
        {
            Console.Write("Escribe la clave: ");
            passw = Console.ReadLine();
            // si la clave tiene caracteres no permitidos, preguntar de nuevo
            valido = UtilSHA1.ValidarTextoClave(passw);
            if (!valido)
                Console.WriteLine("La clave NO ES VÁLIDA.");
        }
        while (!valido);

        // generar la clave SHA1 y mostrarla
        var claveSHA1 = UtilSHA1.GenerarClaveSHA1(usuario, passw);
        Console.WriteLine($"La clave SHA1 es: '{claveSHA1}'.");
    }
}

 

La clase UtilSHA1 con los métodos para comprobar la validez del texto y generar la clave

A continuación te muestro el código del método para validar el texto del nombre del usuario y el password o contraseña para que no contenga caracteres no deseados.

Para Visual Basic:

''' <summary>
''' Validar caracteres en la clave.
''' No se aceptan ?*%'_ ni --
''' </summary>
Public Shared Function ValidarTextoClave(laClave As String) As Boolean
    Dim sNoVale As String = "?*%'_"

    laClave = laClave.Trim()

    If laClave.IndexOf("--") > -1 Then
        Return False
    End If
    If laClave.IndexOfAny(sNoVale.ToCharArray) > -1 Then
        Return False
    End If

    Return True
End Function

 

Para C#:

/// <summary>
/// Validar caracteres en la clave.
/// No se aceptan ?*%'_ ni --
/// </summary>
public static bool ValidarTextoClave(string laClave)
{
    string sNoVale = "?*%'_";

    laClave = laClave.Trim();

    if (laClave.IndexOf("--") > -1)
        return false;
    if (laClave.IndexOfAny(sNoVale.ToCharArray()) > -1)
        return false;

    return true;
}

 

Y ahora el código con la definición del método GenerarClaveSHA1 en el que indicaremos dos cadenas: el nombre del usuario y el password y a partir de la concatenación de ambas generar el valor SHA1 producido por el método ComputeHash que en realidad devuelve un array de tipo Byte, el cual convertimos en valores hexadecimales (con dos cifras por valor) con idea de que se genere la cadena deseada de 40 caracteres en total, que finalmente convertimos en mayúsculas, pero que bien puedes dejarlo en minúsculas si así te parece mejor.

El código para Visual Basic:

''' <summary>
''' Generar una clave SHA1 para guardarla en lugar del password,
''' de esa forma no se podrá saber la clave.
''' La longitud es de 40 caracteres.
''' </summary>
''' <remarks>
''' Crear una clave SHA1 como la generada por:
''' FormsAuthentication.HashPasswordForStoringInConfigFile
''' Basado en el ejemplo de mi sitio:
''' http://www.elguille.info/NET/dotnet/comprobar_usuario_usando_base_datos_vb2003.htm
''' </remarks>
Public Shared Function GenerarClaveSHA1(nick As String, clave As String) As String
    ' Crear una clave SHA1 como la generada por 
    ' FormsAuthentication.HashPasswordForStoringInConfigFile
    ' Adaptada del ejemplo de la ayuda en la descripción de SHA1 (Clase)
    Dim enc As New UTF8Encoding
    ' Por si el usuario (nick) es nulo
    If String.IsNullOrWhiteSpace(nick) Then
        nick = ""
    Else
        nick = nick.ToLower
    End If
    Dim data() As Byte = enc.GetBytes(nick & clave)
    Dim result() As Byte

    Dim sha As New SHA1CryptoServiceProvider
    ' This is one implementation of the abstract class SHA1.
    result = sha.ComputeHash(data)

    ' Convertir los valores en hexadecimal
    ' cuando tiene una cifra hay que rellenarlo con cero
    ' para que siempre ocupen dos dígitos.
    Dim sb As New StringBuilder
    For i As Integer = 0 To result.Length - 1
        If result(i) < 16 Then
            sb.Append("0")
        End If
        sb.Append(result(i).ToString("x"))
    Next

    Return sb.ToString.ToUpper
End Function

 

El código para C#:

/// <summary>
/// Generar una clave SHA1 para guardarla en lugar del password,
/// de esa forma no se podrá saber la clave.
/// La longitud es de 40 caracteres.
/// </summary>
/// <remarks>
/// Crear una clave SHA1 como la generada por:
/// FormsAuthentication.HashPasswordForStoringInConfigFile
/// Basado en el ejemplo de mi sitio:
/// http://www.elguille.info/NET/dotnet/comprobar_usuario_usando_base_datos_cs2003.htm
/// </remarks>
public static string GenerarClaveSHA1(string nick, string clave)
{
    // Crear una clave SHA1 como la generada por 
    // FormsAuthentication.HashPasswordForStoringInConfigFile
    // Adaptada del ejemplo de la ayuda en la descripción de SHA1 (Clase)
    UTF8Encoding enc = new UTF8Encoding();
    // Por si el usuario (nick) es nulo
    if (string.IsNullOrWhiteSpace(nick))
        nick = "";
    else
        nick = nick.ToLower();
    byte[] data = enc.GetBytes(nick + clave);
    byte[] result;

    SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
    // This is one implementation of the abstract class SHA1.
    result = sha.ComputeHash(data);

    // Convertir los valores en hexadecimal
    // cuando tiene una cifra hay que rellenarlo con cero
    // para que siempre ocupen dos dígitos.
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < result.Length; i++)
    {
        if (result[i] < 16)
            sb.Append("0");
        sb.Append(result[i].ToString("x"));
    }

    return sb.ToString().ToUpper();
}

 

Nota:
El código final del método GenerarClaveSHA1 se puede simplificar para que use dos caracteres hexadecimales sin necesidad de la comparación de si el valor es menor de 16.
El código te lo muestro en el repositorio de github por si quieres intentarlo por tu cuenta 😉

 

Nota importante:
Comentarte que la generación de la clave SHA1 distingue entre mayúsculas y minúsculas, es decir, si al generar la clave SHA1 usaste Guillermo como usuario (o nick) si vuelves a generarla con el nombre en minúsculas (guillermo) el valor generado será diferente.
Esto mismo es aplicable a la contraseña o password.

 

El código completo con los proyectos para usar con .NET 5.0 (tanto con dotnet como con Visual Studio Code o con Visual Studio 2019 v16.8) está publicado en github:
Generar clave SHA1 con el nombre y password del usuario.

 

Y esto es todo… espero que te sea de utilidad… ya sabes que esa es la idea… y si te parece bien (y puedes) no estaría de más que dejaras una propina usando el enlace de PayPal 😉
Gracias.

 

Nos vemos.
Guillermo

¿Quieres aprender a programar usando .NET Core sin instalar nada?

Pues eso… me he metido en la página de instalación del .NET Core 3.0 SDK y he visto un botón con el enlace «Get Started» (ver la figura 1) y me ha llevado a la página de .NET Tutorial – Hello World in 10 minutes y en la parte de la izquierda he visto un botón con el texto Try .NET in your browser (ver figura 2) y lo he pulsado… y me ha llevado a una página en la que te va explicando las cosas básicas para crear una aplicación de consola, empezando con el clásico «Hello World!» (ver figura 3) que después ha pasado al «Hello Guillermo!» (o tu nombre) y ha seguido haciendo cambios y enseñando algunas cosas, que al menos yo ya había leído, pero así lo he tenido más claro (ver figura 4)…. bueno, es curioso más que nada… y no acaba ahí la cosa (yo no he seguido) pero se ve que sigue con otras cosas como trabajar con números, aunque esta vez ha cambiado el formato, pero básicamente es en el mismo tono (ver figuras 5 y 6), así que… te lo recomiendo ya que las cosas que incluyen son:

Análisis de las operaciones matemáticas con enteros
Análisis sobre el orden de las operaciones
Información sobre los límites y la precisión de los enteros
Operaciones con el tipo double
Operaciones con tipos de punto fijo

Eso sí, todo con puntos y comas… Smile

Las capturas

Figura 1. Get Started en la página de descarga del .NET Core 3.0 SDK
Figura 1. Get Started en la página de descarga del .NET Core 3.0 SDK

Figura 1.

Figura 2. El tutorial con el botón de Try .NET in your browser
Figura 2. El tutorial con el botón de Try .NET in your browser

Figura 2.

Figura 3. El tutorial de .NET In-Browser
Figura 3. El tutorial de .NET In-Browser

Figura 3.

Figura 4. String Interpolation
Figura 4. String Interpolation

Figura 4.

Figura 5. Aquí acaba el tutorial .NET In-Browser
Figura 5. Aquí acaba el tutorial .NET In-Browser

Figura 5.

Figura 6. El tutorial de C# sigue con el compilador In-Browser
Figura 6. El tutorial de C# sigue con el compilador In-Browser

Los enlaces:

Espero que si no te es de utilidad al menos te relaje un poco… jajajaja

Nos vemos.
Guillermo