sql >> Database teknologi >  >> RDS >> Mysql

Simulering af MySqls password()-kryptering ved hjælp af .NET eller MS SQL

Ifølge MySQL-dokumentation er algoritmen en dobbelt SHA1-hash. Når du undersøger MySQL-kildekoden, finder du en funktion kaldet make_scrambled_password() i libmysql/password.c. Funktionen er defineret som følger:

/*
    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 denne metode kan du oprette en .NET-modpart, der grundlæggende gør det samme. Her er hvad jeg er kommet frem til. Når jeg kører SELECT PASSWORD('test'); mod min lokale kopi af MySQL er den returnerede værdi:

*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29

Ifølge kildekoden (igen i password.c) indikerer den begyndende stjerne, at dette er post-MySQL 4.1-metoden til at kryptere adgangskoden. Når jeg emulerer funktionaliteten i VB.Net for eksempel, er dette hvad jeg kommer frem til:

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

Husk, at SHA1Managed() er i System.Security.Cryptography-navnerummet. Denne metode returnerer det samme output som PASSWORD()-kaldet i MySQL. Jeg håber, at dette hjælper dig.

Edit:Her er den samme kode 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. Hvorfor kan Java ikke oprette forbindelse til MySQL 5.7 efter den seneste JDK-opdatering, og hvordan skal det rettes? (ssl.SSLHandshakeException:Ingen passende protokol)

  2. Få en undtagelse ORA-00942:tabel eller visning findes ikke - ved indsættelse i en eksisterende tabel

  3. MySQL-optimering af INSERT-hastigheden bliver bremset på grund af indekser

  4. Kopier nogle få af kolonnerne i en csv-fil til en tabel