Я пытаюсь прочитать файл, зашифровать его и отправить его на сервер через сокет, где он написан. А потом наоборот, прочитайте его на сервере, отправьте его клиенту, расшифруйте его и запишите снова.C# aes encryption: Размер входного файла не равен размеру
Моя проблема с использованием класса C# Aes заключается в том, что размер ввода не равен размеру вывода.
Например, когда я прочитал 4096 байт из файла, размер вывода составляет 4112 байт, еще 16 байт. ОК, поэтому 4112 байт отправляются и записываются на сервер, но когда я снова получаю файл, я могу отправлять только 4096 байт по сокету, а затем, конечно, функция расшифровки на клиенте выдает исключение, которое отступ недействителен и не может быть удален. Конечно, я мог бы попытаться читать меньше байтов на клиенте, но это не работает.
Я очень опытный программист на С ++, и я сделал это с OpenSsl, и он работал как шарм. Размер ввода всегда был размером вывода, я не знаю, что не так с моими функциями в C#.
это отправка часть:
byte[] SendData = new byte[4096];
iBytesRead = FileRead.Read (SendData, 0, 4096);
SendData = aes.encrypt (Encoding.Default.GetString (SendData, 0, iBytesRead), iBytesRead);
String a = aes.decrypt (SendData); // no problems here because the size is correct
Socket.sendB (SendData, SendData.Length);
и часть приема от сервера:
byte[] WriteData = new byte[4096],
Temp;
if ((iBytesReceived = Socket.receiveB (ref WriteData)) == 0)
break;
if (Encoding.ASCII.GetString (WriteData, 0, iBytesReceived) == "end")
break;
for (uint i = 0; i < iBytesReceived; i++)
Temp[i] = WriteData[i];
byte[] a = Encoding.Default.GetBytes (aes.decrypt (Temp));
FileWrite.Write (a, 0, Temp.Length);
äes функции:
public byte[] encrypt(String _InStr, int _InStrLength)
{
if (!bKeySet)
return ErrorReturn;
byte[] encrypted;
using (Aes aes = Aes.Create())
{
aes.Key = Key;
aes.IV = IV;
//aes.Padding = PaddingMode.PKCS7;
//aes.BlockSize = 128;
//aes.KeySize = 128;
//aes.Mode = CipherMode.CFB;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
// Create the streams used for encryption.
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(_InStr);
}
}
ms.Close();
encrypted = ms.ToArray();
}
}
return encrypted;
}
public String decrypt(byte[] _InStr)
{
if (!bKeySet)
return "";
String plaintext;
using (Aes aes = Aes.Create())
{
aes.Key = Key;
aes.IV = IV;
//aes.Padding = PaddingMode.PKCS7;
//aes.BlockSize = 128;
//aes.KeySize = 128;
//aes.Mode = CipherMode.CBC;
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(_InStr))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
Размер ввода может равняться только размеру выхода при использовании NoPadding. PKCS7Padding всегда производит 1-16 дополнительных байтов (для AES), чтобы заполнить до кратного 16. Таким образом, вы можете попробовать прочитать 4095 байт вместо 4096. Неясно, почему вы не можете использовать меньший буфер. –
@ArtjomB. Затем я получаю это в функции шифрования: «Входные данные не являются полным блоком» – schacker22