Note that there are some explanatory texts on larger screens.

plurals
  1. POSecure File transmission in C# using AES
    primarykey
    data
    text
    <p>I'm trying to read a file on the server (in blocks of 5KB), encrypt the block using AES and send it to the client. On the client, i decrypt the received block, and append to a file to get back the original file.</p> <p>However, my decrypted block size received on the client differs from the plaintext block which is encrypted on the server.</p> <p>e.g. I have a 15.5 KB exe file, so i have 15.5*1024/5*1024 = 4 blocks (round figure) to encrypt and send to client (The first 3 blocks are of 5120 bytes and last block is 512 bytes in length). On the client however, the blocks decrypted are of size 5057, 4970, 5016 and 512 bytes which equals a file size of 15.1 KB (less than what was actually sent by the server). </p> <p>Here is my code snippet:</p> <p>Server (sends the file to client): </p> <pre><code>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 &lt; numberOfBlocks) { byte[] buffer; numberOfBytesToRead = blockSize; if (fs.Length &lt; 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(); </code></pre> <p>Client side code which receives the file:</p> <pre><code>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 &lt; numberOfBlocks) { byte[] encryptedBuffer = ReadMessage(sr); byte[] buffer = objAes.Decrypt(encryptedBuffer, sessionKey, initVector); fs.Write(buffer, 0, buffer.Length); offset += buffer.Length; count++; } fs.Close(); </code></pre> <p>My AES code for encryption:</p> <pre><code>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; } </code></pre> <p>My AES code for decryption:</p> <pre><code> 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)); } </code></pre> <p>These are the results i got while debugging the while loop which sends file blocks on the server:</p> <p>Actual File Size sent: 15.5 KB = 15872 bytes</p> <pre> Buffer size(plaintext) Encrypted Buffer Size(Sent) Offset Count 5120 5136 5120 0 5120 5136 10240 1 5120 5136 15360 2 512 528 15872 3 </pre> <p>These are the results i got while debugging the while loop which receives file blocks on the client:</p> <p>Actual File Size received: 15.1 KB = 15555 bytes</p> <pre> Received Buffersize Decrypted Buffer Size Offset Count 5136 5057 5057 0 5136 4970 10027 1 5136 5016 15043 2 528 512 15555 3 </pre> <p>It is evident that the sending and receiving code is working fine (since encrypted buffer size which is sent = received buffer size). However, the decrypted buffer size does not match the buffer size (plaintext) at all except for the last block which is of length 512 bytes.</p> <p>What can be possibly wrong with decryption because of which i'm not receiving the file completely on the client side?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload