Ошибка при шифровании кода С# при расшифровке!

61
8

Немного больше информации о предыстории, как было предложено:
Я использую веб-приложение Intranet CMS, где я должен использовать API продуктов (на основе ASP.NET). Из-за ограничений по времени и проблем с Windows authen 'Мне нужен другой способ, чтобы сотрудники не нуждались в повторном подключении каждый раз, когда они посещают сайт для просмотра персонализированного контента. Способ его работы заключается в том, что после входа пользователя в систему (имя пользователя/пароль) генерируется идентификатор сеанса, в котором хранится новое значение контекста безопасности, которое используется для отображения персонализированного содержимого. Вызов метода входа в API использует имя пользователя и пароль в качестве параметров. Единственный способ, с помощью которого я могу автоматически регистрироваться в следующий раз, когда сотрудники посещают сайт, - это сохранить пароль в зашифрованном файле cookie и проверить его существующий при посещении сайта, а затем вызвать метод входа в API с использованием имени пользователя и расшифрованного пароля cookie.


Любые другие идеи в качестве альтернативы приветствуются.


Мо


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


Спасибо заранее.


Мо


System.Text.Encoding enc = System.Text.Encoding.ASCII;
byte[] myByteArray = enc.GetBytes(_pword);

SymmetricAlgorithm sa = DES.Create();
MemoryStream msDecrypt = new MemoryStream(myByteArray);
CryptoStream csDecrypt = new CryptoStream(msDecrypt, sa.CreateDecryptor(), CryptoStreamMode.Read);
byte[] decryptedTextBytes = new Byte[myByteArray.Length];
csDecrypt.Read(decryptedTextBytes, 0, myByteArray.Length);
csDecrypt.Close();
msDecrypt.Close();

string decryptedTextString = (new UnicodeEncoding()).GetString(decryptedTextBytes);

спросил(а) 2021-01-14T00:08:46+03:00 1 неделя назад
1
Решение
85

Несколько вещей здесь...


    Вы не должны шифровать пароли обычно. Вы должны hash их.

Если вы решите продолжить путь шифрования...


    Вы используете алгоритм DES. Это считается небезопасным и ошибочным. Я бы рекомендовал взглянуть на алгоритм AES.
    В зависимости от количества данных, с которыми вы работаете, CryptoStream может быть переполнен.
    Использование кодировки ASCII может привести к потере данных, которые не являются ASCII, например кириллическими буквами. Рекомендуемое исправление - использовать что-то еще, например UTF8.

Вот пример:


string text = "Hello";
using (var aes = new AesManaged())
{
var bytes = System.Text.Encoding.UTF8.GetBytes(text);
byte[] encryptedBytes;
using (var encrypt = aes.CreateEncryptor())
{
encryptedBytes = encrypt.TransformFinalBlock(bytes, 0, bytes.Length);
}
byte[] decryptedBytes;
using (var decrypt = aes.CreateDecryptor())
{
decryptedBytes = decrypt.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
}
var decryptedText = System.Text.Encoding.UTF8.GetString(decryptedBytes);
Console.Out.WriteLine("decryptedText = {0}", decryptedText);
}

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


Если вы хотите спуститься по маршруту хеширования, вот небольшой пример:


var textToHash = "hello";
using (SHA1 sha = new SHA1Managed())
{
var bytesToHash = System.Text.Encoding.UTF8.GetBytes(textToHash);
var hash = sha.ComputeHash(bytesToHash);
string base64hash = Convert.ToBase64String(hash);
}

Это использует алгоритм SHA1, который должен отлично работать для паролей, однако вы можете рассмотреть SHA256.


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

ответил(а) 2021-01-14T00:08:46+03:00 1 неделя назад
42

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

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

ответил(а) 2021-01-14T00:08:46+03:00 1 неделя назад
43

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


Чтобы хранить зашифрованные байты, я думаю, вы должны использовать Convert.ToBase64String и Convert.FromBase64String перевести зашифрованный пароль в/из строки.


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


Если текущее свойство Key равно null, метод GenerateKey вызывается для создайте новый случайный ключ. Если текущее свойство IV имеет значение null, Вызывается метод GenerateIV для создания новый случайный IV.


ответил(а) 2021-01-14T00:08:46+03:00 1 неделя назад
43

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


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

ответил(а) 2021-01-14T00:08:46+03:00 1 неделя назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема