De acordo com a documentação do MySQL, o algoritmo é um hash SHA1 duplo. Ao examinar o código fonte do MySQL, você encontra uma função chamada make_scrambled_password() em libmysql/password.c. A função é definida da seguinte forma:
/*
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, você pode criar uma contraparte .NET que basicamente faz a mesma coisa. Aqui está o que eu inventei. Quando executo SELECT PASSWORD('test'); contra minha cópia local do MySQL, o valor retornado é:
*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29
De acordo com o código-fonte (novamente em password.c), o asterisco inicial indica que este é o método pós-MySQL 4.1 de criptografar a senha. Quando eu emulo a funcionalidade no VB.Net, por exemplo, é isso que eu faço:
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
Tenha em mente que SHA1Managed() está no namespace System.Security.Cryptography. Este método retorna a mesma saída que a chamada PASSWORD() no MySQL. Espero que isso ajude para você.
Edit:Aqui está o mesmo código em 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();
}