Изменение пароляФормат от зашифрованного до хеширования

Я нахожу удивительно мало информации о преобразовании существующей базы данных из зашифрованных паролей в хэшированные пароли. (Мне удалось найти немного больше информации о преобразовании в другую сторону, но это не помогло.)

Как известно большинству людей, изменение параметра passwordFormat в web.config влияет только на новых пользователей. У меня есть база данных с несколькими сотнями пользователей, и я бы хотел конвертировать их для использования хешированных паролей без изменения существующих паролей.

Кто-нибудь еще знаком с тем, как можно приблизиться к этому? Спасибо за любые советы.

Ответы

Ответ 1

Это тот подход, который я начал бы с того, чтобы узнать, как далеко я получил:

  • Создайте два элемента MembershipProviders в моем web.config, один для зашифрованных паролей и один для хэширования.
  • Прокрутите список всех пользователей, пользующихся зашифрованным паролем. (SqlMembershipProvider.GetAllUsers)
  • Получить пароль пользователя с помощью поставщика зашифрованных паролей. (MembershipUser.GetPassword)
  • Измените пароль пользователя на тот же пароль, используя хешированный пароль. (MembershipUser.ChangePassword)

Итак, это будет примерно так:

    <membership defaultProvider="HashedProvider">
        <providers>
            <clear />
            <add name="HashedProvider" connectionStringName="MembershipConnectionString" enablePasswordRetrieval="false"  requiresQuestionAndAnswer="false" applicationName="MyApp" passwordFormat="Hashed"  type="System.Web.Security.SqlMembershipProvider" />
            <add name="EncryptedProvider" connectionStringName="MembershipConnectionString" enablePasswordRetrieval="true" requiresQuestionAndAnswer="false" applicationName="MyApp" passwordFormat="Encrypted" type="System.Web.Security.SqlMembershipProvider" />
        </providers>
    </membership>

код:

SqlMembershipProvider hashedProvider = (SqlMembershipProvider)Membership.Providers["HashedProvider"];
SqlMembershipProvider encryptedProvider = (SqlMembershipProvider)Membership.Providers["EncryptedProvider"];

int unimportant;
foreach (MembershipUser user in encryptedProvider.GetAllUsers(0, Int32.MaxValue, out unimportant ))
{
    hashedProvider.ChangePassword(user.UserName, user.GetPassword(), user.GetPassword());
}

Ответ 2

Решение Greg - хорошее начало, но оно не повлияет на существующих пользователей. SqlMembershipProvider защищает существующих пользователей и пароли, сохраняя в таблице PasswordFormat (0 = clear, 1 = Hashed, 2 = Encrypted) вместе с паролями. Изменение формата пароля поставщика влияет только на вставки в пользовательские таблицы. Чтобы преобразовать пароли существующих пользователей в Hashed, вам необходимо изменить параметр PasswordFormat для каждой записи. Вот простой способ сделать это:

void HashAllPasswords()
{
    var clearProvider = Membership.Providers["SqlProvider_Clear"];
    var hashedProvider = Membership.Providers["SqlProvider_Hashed"];
    int dontCare;
    if (clearProvider == null || hashedProvider == null) return;
    var passwords = clearProvider.GetAllUsers(0, int.MaxValue, out dontCare)
        .Cast<MembershipUser>().ToDictionary(u => u.UserName, u => u.GetPassword());

    using (var conn = new SqlConnection(
           ConfigurationManager.ConnectionStrings[0].ConnectionString))
    {
        conn.Open();
        using (var cmd = new SqlCommand(
               "UPDATE [aspnet_Membership] SET [PasswordFormat]=1", conn))
            cmd.ExecuteNonQuery();
    }

    foreach (var entry in passwords)
    {
        var resetPassword = hashedProvider.ResetPassword(entry.Key, null);
        hashedProvider.ChangePassword(entry.Key, resetPassword, entry.Value);
    }
}

Ответ 3

В целях безопасности это определенно правильное решение переключиться с зашифрованных паролей на хеши в вашей базе данных.

Как правило, чтобы создать хэши из существующих зашифрованных паролей, вы должны сначала их расшифровать, а затем использовать их. Имейте в виду, что вы потеряете (когда вы окончательно переключите) исходные пароли. Вместо этого у вас будет уникальный отпечаток (хэш) паролей пользователей.

Подумайте также об использовании соли для хеширования (защита от радужных таблиц и т.д.), а также посмотрите на медленные алгоритмы хеширования, такие как BCrypt (Codeplex и Статья: безопасное сохранение пароля) по соображениям безопасности вместо быстрых, таких как MD5.

Имейте в виду, что в будущем будет больше усилий для переключения алгоритма хэширования, чем изменение его с помощью шифрования на хэш. Итак, вы хотите сделать это в первый раз;)

Ответ 4

Я бы предостерег вас от случайного хеширования ваших паролей, поскольку для этого подхода существует много предостережений. Это сообщение Blog о хэшировании паролей было очень проницательным для меня, и я думаю, что вы должны его прочитать. Почему вы хотите хешировать пароли вместо шифрования?