Имитация шифрования пароля () MySql с использованием .NET или MS SQL - PullRequest
6 голосов
/ 15 мая 2009

Я обновляю старое веб-приложение ASP / MySql до ASP.NET/MS SQL.

Мы бы хотели, чтобы логины со старого сайта работали в новом приложении.

К сожалению, пароли были сохранены в БД MySql с помощью функции пароля () MySql.

Можно ли имитировать функцию пароля () MySql в .NET или MS SQL?

Любая помощь / ссылки приветствуются.

Ответы [ 7 ]

13 голосов
/ 15 мая 2009

Согласно документации MySQL, алгоритм представляет собой двойной хэш SHA1. При проверке исходного кода MySQL вы найдете функцию make_scrambled_password () в libmysql / password.c. Функция определяется следующим образом:

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

Используя этот метод, вы можете создать аналог .NET, который в основном делает то же самое. Вот что я придумала. Когда я запускаю SELECT PASSWORD («тест»); для моей локальной копии MySQL возвращаемое значение:

*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29

Согласно исходному коду (снова в password.c), начинающаяся звездочка указывает, что это метод шифрования пароля после MySQL 4.1. Например, когда я эмулирую функциональность в VB.Net, я придумываю следующее:

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

Учтите, что SHA1Managed () находится в пространстве имен System.Security.Cryptography. Этот метод возвращает тот же вывод, что и вызов PASSWORD () в MySQL. Я надеюсь, что это поможет вам.

Редактировать: вот тот же код в 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 голос
/ 29 октября 2010

C # версия изменена, чтобы исправить проблему с заполнением.
[Тестовое задание] public void GenerateMySQLHashX2 () { строка пароль = "20iva05";

        byte[] keyArray = Encoding.UTF8.GetBytes(password);
        SHA1Managed enc = new SHA1Managed();
        byte[] encodedKey = enc.ComputeHash(enc.ComputeHash(keyArray));
        StringBuilder myBuilder = new StringBuilder(encodedKey.Length);

        foreach (byte b in encodedKey)
        {
            log.Debug(b.ToString() + "    ->   " +  b.ToString("X2"));
            myBuilder.Append(b.ToString("X2"));
        }

        Assert.AreEqual("*8C2029A96507478FD1720F6B713ADD57C66EED49", "*" + myBuilder.ToString());
    } 
1 голос
/ 14 июня 2010

"они не собираются раскрывать, что алгоритм, который они используют "

эм ... кто-то должен проснуться и сказать вам, что MySQL OPEN SOURCE ... им не нужно «раскрывать» что-то, потому что каждый может прочитать саму структуру базы данных - просто скачайте исходники , найдите функции шифрования (я думаю, они используют C ++) и начните расследование ... SHA1 кажется довольно небезопасным - совсем недавно несколько ученых доказали, что можно выбирать до 20% данных без ограничений и генерировать тот же хеш , поэтому можно посоветовать использовать AES или SHA2 (поэтому не MySQL- ПАРОЛЬ -func)

1 голос
/ 15 мая 2009

Вы можете шифровать строки, используя MD5 или SHA1 в .Net, но фактический алгоритм, используемый MySQL, вероятно, отличается от этих двух методов. Я подозреваю, что это основано на некоторой «соли», основанной на экземпляре сервера, но я не знаю.

Теоретически, поскольку я считаю, что MySQL является открытым исходным кодом, вы можете исследовать источник и определить, как это делается.

http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html#function_password

Редактировать 1: Я полагаю, что используемый алгоритм представляет собой двойной SHA1 с другими «хитростями» (согласно этому сообщению в блоге).

0 голосов
/ 11 октября 2010

функции пароля mysql не особенно безопасны (например, нет соли или другого метода защиты от поиска подходящих хэшей) единственные причины, по которым я могу увидеть дублирование алгоритма, 1: у вас есть список / таблица пользователей с mysql password () s 2: вы хотите взломать пароли mysql из хешей в пользовательской таблице.

В противном случае используйте что-то другое, например, хеш, который объединяет имя пользователя (и / или некоторый другой инвариант строки) и его пароль. Кстати, если два пользователя выберут один и тот же пароль, это не будет очевидным. и если таблица выставляется, безопасность не уменьшается с той же скоростью (например, Google для 446a12100c856ce9, который является паролем () хеш очень популярного пароля)

0 голосов
/ 18 августа 2009

Для сети VB это дополняется нулями слева, поэтому, когда шестнадцатеричный код [например] 'E', эта функция правильно добавит '0E' к строке результата. Так что в конце, включая префикс «*», результирующая строка будет иметь длину 41 символ, как это требуется в MySQL

Public Function GenerateMySQLHash(ByVal strKey As String) As String

    Dim keyArray As Byte() = System.Text.UTF8Encoding.UTF8.GetBytes(strKey)
    Dim enc = New Security.Cryptography.SHA1Managed()
    Dim encodedKey = enc.ComputeHash(enc.ComputeHash(keyArray))
    Dim myBuilder As New System.Text.StringBuilder(encodedKey.ToString.Length)

    For Each b As Byte In encodedKey
        myBuilder.Append(Strings.Right("0" & b.ToString("X"), 2))
    Next

    Return "*" & myBuilder.ToString()
End Function
0 голосов
/ 15 мая 2009

Вы не сможете смоделировать функцию пароля MySql (). по крайней мере, не без большой работы и удачи. Поскольку MySql использует свой собственный алгоритм для одностороннего шифрования строк, они не собираются раскрывать, какой алгоритм они используют; Это означает, что вам придется делать проб и ошибок, сравнивать полученные строки и т. д.

Чтобы исправить вашу проблему:

Я бы копировал БД, но поддерживал соединение с MySql. Используйте флаг, чтобы идентифицировать первый вход в систему. Попросите их использовать свой текущий пароль; проверить пароль с помощью функции пароля MySql (). Если пароль действителен; попросите их сбросить его, либо введя тот же пароль еще раз, либо новый; на этом этапе используйте ваш любимый алгоритм шифрования и сохраните результат в вашей MS Sql DB.

Я знаю, это звучит как боль, но это лучшее, что вы можете сделать, если не попытаться взломать свой путь к расшифровке алгоритма шифрования MySql.

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...