Расшифровка зашифрованного пароля от членства ASP.NET с помощью RijndaelManaged - PullRequest
2 голосов
/ 29 декабря 2011

Суть в том, чтобы создать пользовательский провайдер аутентификации FTP .Для этого нужно наследовать от интерфейса IFtpAuthenticationProvider и затем зарегистрировать эту сборку в GAC.После этого сборка должна быть зарегистрирована в настройках FTP IIS.

Для этого мне нужно использовать базу данных, в которой хранится информация о моем пользователе в базе данных от пользовательских провайдеров членства и ролей, которые мы разработали.ранее.Таким образом, это означает, что я должен использовать файл локальной библиотеки классов app.config и читать его с ConfigurationManager.OpenMappedExeConfiguration().Оттуда я читаю строки подключения и даже могу динамически предоставлять их классам Linq-To-Sql .Никаких проблем.

Далее я пытаюсь создать класс, который наследуется от SqlMembershipProvider , чтобы я мог использовать его собственную систему для расшифровки пароля для пользователя.Но проблема в том, что он должен прочитать machineKey значения из конфигурации.Единственный способ предоставить пользовательскую конфигурацию SqlMembershipProvider - это метод Initialize (который в любом случае не предназначен для его использования в нашем коде).Но все равно я попытался и потерпел неудачу.Я смог предоставить ему пользовательские настройки членства, но не настройки machineKey.

Итак, я решил пойти радикально.Я сказал: у меня есть decryptionKey из machineKey, поэтому я попытаюсь расшифровать пароль вручную.

Пока я пытался использовать RijndaelManaged:

    private string UnEncodePassword(string encodedPassword, string secretKey)
    {
        string password = encodedPassword;

        var keyBytes = new byte[16];
        var secretKeyBytes = Encoding.UTF8.GetBytes(secretKey);
        Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));

        RijndaelManaged rm = new RijndaelManaged
        {
            Mode = CipherMode.CBC,
            Padding = PaddingMode.PKCS7,
            KeySize = 128,
            BlockSize = 128,
            Key = keyBytes,
            IV = keyBytes
        };

        var encryptedBytes = Convert.FromBase64String(encodedPassword);
        password = Encoding.UTF8.GetString(Decrypt(encryptedBytes, rm));

        return password;
    }

Я отчасти осознаю, что здесь снимаю пробелы, так как я не уверен, какой вид заполнения используется, и, что важнее, даже если бы я мог, я не выбрал правильный IV.Лучшее, что я сделал до сих пор, - это получил какой-то хреновый ответ, вроде: �21l� <�� (� \ t��]. </p>

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

РЕДАКТИРОВАТЬ:

Просто чтобы сделать вещи немного более понятными. Я не пытаюсь взломать пароль или что-нибудь. Яу меня есть пароль, и у меня есть decryptionKey и т. д. Я просто хочу найти способ зашифровать / расшифровать его, чтобы я мог выполнить проверку пользователя.
Я полностью осознаю, что шифрование / дешифрование паролей не лучший подход впервое место, но есть причины, почему это делается именно так.

Ответы [ 3 ]

5 голосов
/ 29 декабря 2011

Вы не должны расшифровывать пароли. Вы должны сравнивать хэши паролей.

Пароли не должны храниться с обратимым шифрованием. Пароли должны храниться в виде хэшей (не слишком слабый MD5).

Что касается вашего комментария выше, вам не нужно расшифровывать пароли для их сравнения. Вы хотите сравнить хэши, а не исходные значения. Система не должна иметь возможности получить исходный текст пароля. Использование встроенных поставщиков членства ASP.NET правильно сохраняет пароли в виде хэшей. Вероятно, поэтому вы не можете их расшифровать, их невозможно расшифровать.

Редактировать: В связи с тем, что вы используете passwordFormat="Encrypted" для поставщика членства SQL. С этим фактом вы можете либо зашифровать пароль в том же формате, с тем же заполнением, cipherMode и IV (вам потребуется запросить это из базы данных SQL), а затем просто сравнить зашифрованные значения пароля. Это скорее всего ненужная работа. Вы действительно просто хотите вызвать функцию входа в членство в коде с комбинацией имени пользователя и пароля и проверить, успешно ли это или нет. Вам нужно убедиться, что ключи машин и соответствующие детали совпадают в обеих системах, иначе вы не сможете добиться успеха.

Вы действительно хотите планировать переход на хешированные пароли, однако хранить зашифрованные пароли в отличие от хешированных паролей практически бессмысленно. Это только немного лучше, чем хранить их в виде простого текста.

1 голос
/ 29 декабря 2011

Я согласен с другими, что хешированные пароли, как правило, более безопасны, чем зашифрованные.

Но поскольку вы не можете выбрать, почему вы должны использовать методы Encryption или Decription из MembershipProvider (кстати, я даже не думаю, что это возможно).

Почему бы вам не создать свои собственные методы шифрования и не использовать их в веб-приложении и вашей библиотеке классов.

1 голос
/ 29 декабря 2011

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

Традиционно, следует хранить только соленый хэш пароля в вашей базе данных. Хеширование - это односторонняя операция (поэтому никто не сможет расшифровать информацию, чтобы узнать пароли, если ваша база данных взломана).

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

Алгоритм аутентификации должен выглядеть примерно так:

  1. Получить соль для хеширования (возможно, вы используете сольуникальный для каждого пользователя или глобальный)
  2. Создание хэша пароля пользователя.
  3. Сравните хешированный пароль с паролем, сохраненным в вашей базе данных для указанного имени пользователя (если используется LINQ-to-SQL, простой оператор Any может сделать это).
  4. Возвращает значение, указывающее успех или неудачу.
...