Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Simulation der password()-Verschlüsselung von MySql mit .NET oder MS SQL

Laut MySQL-Dokumentation ist der Algorithmus ein doppelter SHA1-Hash. Wenn Sie den MySQL-Quellcode untersuchen, finden Sie eine Funktion namens make_scrambled_password() in libmysql/password.c. Die Funktion ist wie folgt definiert:

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

Mit dieser Methode können Sie ein .NET-Gegenstück erstellen, das im Grunde dasselbe tut. Hier ist, was ich mir ausgedacht habe. Wenn ich SELECT PASSWORD('test'); Im Gegensatz zu meiner lokalen MySQL-Kopie lautet der zurückgegebene Wert:

*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29

Laut Quellcode (wieder in password.c) zeigt das beginnende Sternchen an, dass dies die Post-MySQL 4.1-Methode zur Verschlüsselung des Passworts ist. Wenn ich zum Beispiel die Funktionalität in VB.Net emuliere, komme ich auf Folgendes:

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

Beachten Sie, dass sich SHA1Managed() im System.Security.Cryptography-Namespace befindet. Diese Methode gibt dieselbe Ausgabe zurück wie der PASSWORD()-Aufruf in MySQL. Ich hoffe, das hilft Ihnen.

Bearbeiten:Hier ist der gleiche 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();
}