sql >> Databasteknik >  >> RDS >> Mysql

Simulering av MySqls lösenord()-kryptering med .NET eller MS SQL

Enligt MySQL-dokumentation är algoritmen en dubbel SHA1-hash. När du undersöker MySQL-källkoden hittar du en funktion som heter make_scrambled_password() i libmysql/password.c. Funktionen definieras enligt följande:

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

Med den här metoden kan du skapa en .NET-motsvarighet som i princip gör samma sak. Här är vad jag har kommit på. När jag kör SELECT PASSWORD('test'); mot min lokala kopia av MySQL är värdet som returneras:

*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29

Enligt källkoden (igen i password.c) indikerar den inledande asterisken att detta är post-MySQL 4.1-metoden för att kryptera lösenordet. När jag emulerar funktionaliteten i VB.Net till exempel, är detta vad jag kommer på:

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

Tänk på att SHA1Managed() finns i namnområdet System.Security.Cryptography. Denna metod returnerar samma utdata som PASSWORD()-anropet i MySQL. Jag hoppas att detta hjälper dig.

Edit:Här är samma kod i 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. Android:öppnar och stänger SQLite-databas

  2. SQL Server matematiska funktioner (fullständig lista)

  3. GROUP BY utan aggregatfunktion

  4. Använda Jenkins med Kubernetes AWS, del 3