sql >> Base de Datos >  >> RDS >> Mysql

Simulando el cifrado de contraseña () de MySql usando .NET o MS SQL

Según la documentación de MySQL, el algoritmo es un hash SHA1 doble. Al examinar el código fuente de MySQL, encontrará una función llamada make_scrambled_password() en libmysql/password.c. La función se define de la siguiente manera:

/*
    MySQL 4.1.1 password hashing: SHA conversion (see RFC 2289, 3174) twice
    applied to the password string, and then produced octet sequence is
    converted to hex string.
    The result of this function is used as return value from PASSWORD() and
    is stored in the database.
  SYNOPSIS
    make_scrambled_password()
    buf       OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string
    password  IN  NULL-terminated password string
*/

void
make_scrambled_password(char *to, const char *password)
{
  SHA1_CONTEXT sha1_context;
  uint8 hash_stage2[SHA1_HASH_SIZE];

  mysql_sha1_reset(&sha1_context);
  /* stage 1: hash password */
  mysql_sha1_input(&sha1_context, (uint8 *) password, (uint) strlen(password));
  mysql_sha1_result(&sha1_context, (uint8 *) to);
  /* stage 2: hash stage1 output */
  mysql_sha1_reset(&sha1_context);
  mysql_sha1_input(&sha1_context, (uint8 *) to, SHA1_HASH_SIZE);
  /* separate buffer is used to pass 'to' in octet2hex */
  mysql_sha1_result(&sha1_context, hash_stage2);
  /* convert hash_stage2 to hex string */
  *to++= PVERSION41_CHAR;
  octet2hex(to, (const char*) hash_stage2, SHA1_HASH_SIZE);
}

Dado este método, puede crear una contraparte de .NET que básicamente hace lo mismo. Esto es lo que se me ocurrió. Cuando ejecuto SELECT PASSWORD('test'); contra mi copia local de MySQL, el valor devuelto es:

*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29

Según el código fuente (nuevamente en password.c), el asterisco inicial indica que este es el método posterior a MySQL 4.1 para cifrar la contraseña. Cuando imilo la funcionalidad en VB.Net, por ejemplo, esto es lo que se me ocurre:

Public Function GenerateMySQLHash(ByVal strKey As String) As String
    Dim keyArray As Byte() = Encoding.UTF8.GetBytes(strKey)
    Dim enc = New SHA1Managed()
    Dim encodedKey = enc.ComputeHash(enc.ComputeHash(keyArray))
    Dim myBuilder As New StringBuilder(encodedKey.Length)

    For Each b As Byte In encodedKey
        myBuilder.Append(b.ToString("X2"))
    Next

    Return "*" & myBuilder.ToString()
End Function

Tenga en cuenta que SHA1Managed() está en el espacio de nombres System.Security.Cryptography. Este método devuelve el mismo resultado que la llamada PASSWORD() en MySQL. Espero que esto te ayude.

Editar:Aquí está el mismo código en C#

public string GenerateMySQLHash(string key)
{
    byte[] keyArray = Encoding.UTF8.GetBytes(key);
    SHA1Managed enc = new SHA1Managed();
    byte[] encodedKey = enc.ComputeHash(enc.ComputeHash(keyArray));
    StringBuilder myBuilder = new StringBuilder(encodedKey.Length);

    foreach (byte b in encodedKey)
        myBuilder.Append(b.ToString("X2"));

    return "*" + myBuilder.ToString();
}