sql >> Database >  >> RDS >> Mysql

Simuleren van MySql's wachtwoord() encryptie met .NET of MS SQL

Volgens MySQL-documentatie is het algoritme een dubbele SHA1-hash. Bij het onderzoeken van de MySQL-broncode vindt u een functie genaamd make_scrambled_password() in libmysql/password.c. De functie is als volgt gedefinieerd:

/*
    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);
}

Met deze methode kunt u een .NET-tegenhanger maken die in principe hetzelfde doet. Dit is wat ik heb bedacht. Wanneer ik SELECT PASSWORD ('test') uitvoer; tegen mijn lokale kopie van MySQL is de geretourneerde waarde:

*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29

Volgens de broncode (opnieuw in password.c), geeft het beginsterretje aan dat dit de post-MySQL 4.1-methode is om het wachtwoord te versleutelen. Als ik bijvoorbeeld de functionaliteit in VB.Net emuleer, kom ik op dit uit:

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

Houd er rekening mee dat SHA1Managed() zich in de naamruimte System.Security.Cryptography bevindt. Deze methode retourneert dezelfde uitvoer als de PASSWORD()-aanroep in MySQL. Ik hoop dat dit je helpt.

Bewerken:hier is dezelfde code in 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();
}


  1. Belang van het onderhouden van een HIPAA-compatibele database

  2. Een opgeslagen functieaanroep optimaliseren in SELECT- en WHERE-clausules

  3. Hoe orkestrale/tenanti gebruiken in Laravel 5 om een ​​toepassing met meerdere huurders te bouwen met meerdere databases?

  4. Records verwijderen voor een bepaalde datum