#c# #.net #encryption #cryptography
Вопрос:
Все,
Пожалуйста, посмотрите на код ниже. Код шифрования и дешифрования работает неправильно. Когда я передаю строку «Привет, мир», я получаю ответ «Привет, во». Я всегда теряю байты и не могу понять, почему. Должна быть какая-то причина для этого, тонкая ошибка?
private static void _TestEncryption2()
{
var testText = "Hello world";
var plainBytes = Encoding.Unicode.GetBytes(testText);
var cipher = Rijndael.Create();
cipher.Padding = PaddingMode.PKCS7;
//var _key = Convert.FromBase64String(KEY);
//var _IV = Convert.FromBase64String(IV);
var _key = cipher.Key;
var _IV = cipher.IV;
byte[] cipherBytes;
byte[] decryptedBytes;
var enc = cipher.CreateEncryptor(_key, _IV);
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, enc, CryptoStreamMode.Write))
{
cryptoStream.Write(plainBytes, 0, plainBytes.Length);
}
cipherBytes = memoryStream.ToArray();
}
var dec = cipher.CreateDecryptor(_key, _IV);
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, dec, CryptoStreamMode.Write))
{
cryptoStream.Write(cipherBytes, 0, cipherBytes.Length);
decryptedBytes = memoryStream.ToArray();
}
}
var decryptedText = Encoding.Unicode.GetString(decryptedBytes);
}
Ответ №1:
Избавьтесь от своего второго cryptoStream
, прежде чем делать memoryStream.ToArray()
:
var dec = cipher.CreateDecryptor(_key, _IV);
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, dec, CryptoStreamMode.Write))
{
cryptoStream.Write(cipherBytes, 0, cipherBytes.Length);
}
// Here
decryptedBytes = memoryStream.ToArray();
}
Проблема в том, что второй CryptoStream
не был сброшен до того, как вы прочитали его вывод, и он все еще удерживает этот последний блок внутри.
Размер вашего блока составляет 16 байт, и вы используете UTF-16, который использует 2 байта на символ, поэтому тот факт, что вы получаете первый блок из 8 символов (16 байт), но не последний блок, имеет смысл здесь.
Кроме того, Encoding.Unicode
это UTF-16, что является немного странным выбором в наши дни. По умолчанию должно быть Encoding.UTF8
.
Комментарии:
1. Вау, как я это пропустил 🙁 Спасибо!!! Мы выбрали UTF16, чтобы он соответствовал размеру строки Юникода в файле .net. Теперь, когда я думаю об этом, UTF8 был бы более эффективным, поскольку мы говорим о кодировании.
2. Все неправильно понимают порядок утилизации криптографических материалов. Я увидел название и заподозрил это; прочитал описание и знал наверняка, еще до того, как прочитал код. Ты в хорошей компании!