サーバー上のファイル (5KB のブロック単位) を読み取り、AES を使用してブロックを暗号化し、クライアントに送信しようとしています。クライアントでは、受信したブロックを復号化し、ファイルに追加して元のファイルを取得します。
ただし、クライアントで受信した復号化されたブロック サイズは、サーバーで暗号化されたプレーンテキスト ブロックとは異なります。
たとえば、15.5 KB の exe ファイルがあるので、15.5*1024/5*1024 = 4 ブロック (丸数字) を暗号化してクライアントに送信します (最初の 3 ブロックの長さは 5120 バイトで、最後のブロックの長さは 512 バイトです)。 . ただし、クライアントでは、復号化されたブロックのサイズは 5057、4970、5016、および 512 バイトであり、これは 15.1 KB のファイル サイズに相当します (サーバーによって実際に送信されたものよりも小さい)。
ここに私のコードスニペットがあります:
サーバー (ファイルをクライアントに送信):
FileStream fs = new FileStream("lcd.exe", FileMode.Open, FileAccess.Read);
//block size = 5KB
int blockSize = 5 * 1024;
//calculate number of blocks in data
long numberOfBlocks = fs.Length / blockSize;
if (fs.Length % blockSize != 0) numberOfBlocks++;
byte[] numberOfBlocksBytes = BitConverter.GetBytes(numberOfBlocks);
//send number of blocks to client
SendMessage(sw, numberOfBlocksBytes);
int count = 0, offset = 0, numberOfBytesToRead=0;
Aes objAes = new Aes();
while (count < numberOfBlocks)
{
byte[] buffer;
numberOfBytesToRead = blockSize;
if (fs.Length < offset + blockSize)
{
numberOfBytesToRead = (int)(fs.Length - offset);
}
buffer = new byte[numberOfBytesToRead];
fs.Read(buffer, 0, numberOfBytesToRead);
//encrypt before sending
byte[] encryptedBuffer = objAes.Encrypt(buffer, Encoding.Default.GetBytes(sessionKey), initVector);
SendMessage(sw, encryptedBuffer);
offset += numberOfBytesToRead;
count++;
}
fs.Close();
ファイルを受け取るクライアント側のコード:
byte[] numberOfBlocksBytes = ReadMessage(sr);
long numberOfBlocks = BitConverter.ToInt64(numberOfBlocksBytes, 0);
FileStream fs = new FileStream("lcd.exe", FileMode.Append, FileAccess.Write);
//block size = 5KB
int blockSize = 5 * 1024;
Aes objAes = new Aes();
int count = 0, offset = 0;
while (count < numberOfBlocks)
{
byte[] encryptedBuffer = ReadMessage(sr);
byte[] buffer = objAes.Decrypt(encryptedBuffer, sessionKey, initVector);
fs.Write(buffer, 0, buffer.Length);
offset += buffer.Length;
count++;
}
fs.Close();
暗号化のための私の AES コード:
private const int StandardKeyLength = 16;
public byte[] Encrypt(byte[] plainText, byte[] key, byte[] initVector)
{
if (key.Length != StandardKeyLength | initVector.Length != StandardKeyLength)
{
throw new ArgumentException("Key Length and Init Vector should be 16 bytes (128 bits) in size");
}
var bPlainBytes = plainText;
var objRm = new RijndaelManaged();
objRm.Key = key;
objRm.IV = initVector;
objRm.Padding = PaddingMode.PKCS7;
objRm.BlockSize = 128;
var ict = objRm.CreateEncryptor(objRm.Key, objRm.IV);
var objMs = new MemoryStream();
var objCs = new CryptoStream(objMs, ict, CryptoStreamMode.Write);
objCs.Write(bPlainBytes, 0, bPlainBytes.Length);
objCs.FlushFinalBlock();
var bEncrypted = objMs.ToArray();
return bEncrypted;
}
復号化のための私の AES コード:
public byte[] Decrypt(byte[] cipherText, byte[] key, byte[] initVector)
{
if (key.Length != StandardKeyLength | initVector.Length != StandardKeyLength)
{
throw new ArgumentException("Key Length and Init Vector should be 16 bytes (128 bits) in size");
}
var bCipherBytes = cipherText;
var objRm = new RijndaelManaged();
objRm.Key = key;
objRm.IV = initVector;
objRm.Padding = PaddingMode.PKCS7;
objRm.BlockSize = 128;
var ict = objRm.CreateDecryptor(objRm.Key, objRm.IV);
var objMs = new MemoryStream(bCipherBytes);
var objCs = new CryptoStream(objMs, ict, CryptoStreamMode.Read);
var streamobj = new StreamReader(objCs);
var strDecrypted = streamobj.ReadToEnd();
return (Encoding.Default.GetBytes(strDecrypted));
}
これらは、サーバー上でファイル ブロックを送信する while ループをデバッグしているときに得た結果です。
送信された実際のファイル サイズ: 15.5 KB = 15872 バイト
バッファサイズ(平文) 暗号化バッファサイズ(送信) オフセット数 5120 5136 5120 0 5120 5136 10240 1 5120 5136 15360 2 512 528 15872 3
これらは、クライアントでファイル ブロックを受け取る while ループをデバッグしているときに得た結果です。
受信した実際のファイル サイズ: 15.1 KB = 15555 バイト
受信バッファサイズ 復号バッファサイズ オフセット数 5136 5057 5057 0 5136 4970 10027 1 5136 5016 15043 2 528 512 15555 3
送信コードと受信コードが正常に動作していることは明らかです (送信される暗号化されたバッファー サイズ = 受信バッファー サイズであるため)。ただし、復号化されたバッファ サイズは、長さが 512 バイトの最後のブロックを除いて、バッファ サイズ (平文) とまったく一致しません。
クライアント側でファイルを完全に受信していないため、復号化の何が問題になる可能性がありますか?