Note that there are some explanatory texts on larger screens.

plurals
  1. POAES encryption and decryption resulting in file different than original
    primarykey
    data
    text
    <p>I've decided to implement encryption for file transfers in my service. File transfers prior to this were not encrypted, and they were sent and received flawlessly with the exact same number of bytes.</p> <p>Now I've introduced <code>asymmetrical</code> and <code>symmetrical</code> encryption into the mix to encrypt the data as it passes over the TCP protocol. I use <code>asymmetrical</code> to do an initial handshake passing the <code>symmetrical</code> key to the other party encrypted by the <code>asymmetric</code> public key. From then on out, the receiver of the file calls the sender periodically, and the sender generates a new <code>initialization vector</code>, encrypts the data with the <code>symmetric</code> key, and sends it over to be decrypted by the receiver using the IV and same <code>symmetric</code> key.</p> <p>The chunk size I'm using is 2mb, such that the byte size of the generated chunks, with exception to the last chunk which varies, is <code>2097152</code>. When AES encrypts this file with <code>PaddingMode.PKCS7</code> and <code>CipherMode.CBC</code>, the resulting byte size is <code>2097168</code>. It's gained about 16 bytes during the encryption process.</p> <p>Now initially I thought this is where my problem was, but when I decrypt the data on the receiving end, it goes back to the <code>2097152</code> byte length and I write it to the file. I've proven to myself that it does indeed encrypt and decrypt the data.</p> <p>On a small enough file, the file sizes from the original to the sender seem to be exactly the same. However, as I step up to larger file sizes, there exists a descrepency. On a video file(Wildlife.wmv from windows 7 install) of size <code>26,246,026 bytes</code>, I am instead receiving a finished transfer that is of <code>26,246,218 bytes</code>.</p> <p>Why is there this size difference? What am I doing wrong here?</p> <p>Here's some of my code.</p> <p>For my encryption I am using the following class to encrypt or decrypt, returning a result in the form of a byte array.</p> <pre><code>public class AesCryptor { public byte[] Encrypt(byte[] data, byte[] key, byte[] iv) { using (SymmetricAlgorithm aes = new AesManaged()) { aes.Key = key; aes.IV = iv; aes.Padding = PaddingMode.PKCS7; aes.Mode = CipherMode.CBC; using (ICryptoTransform encryptor = aes.CreateEncryptor(key, iv)) { return Crypt(data, key, iv, encryptor); } } } public byte[] Decrypt(byte[] data, byte[] key, byte[] iv) { using (SymmetricAlgorithm aes = new AesManaged()) { aes.Key = key; aes.IV = iv; aes.Padding = PaddingMode.PKCS7; aes.Mode = CipherMode.CBC; using (ICryptoTransform decryptor = aes.CreateDecryptor(key, iv)) { return Crypt(data, key, iv, decryptor); } } } private byte[] Crypt(byte[] data, byte[] key, byte[] iv, ICryptoTransform transform) { using (MemoryStream memoryStream = new MemoryStream()) { using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write)) { cryptoStream.Write(data, 0, data.Length); cryptoStream.FlushFinalBlock(); } return memoryStream.ToArray(); } } } </code></pre> <p>The sender of the file is encrypting the data(after the handshake of the private symmetric key) with this code(and a lot more that doesn't pertain to the actual encryption process. Note the chunkedFile.NextChunk(). This calls a method on the class that is doing the file chunking for me, returning 2mb chunk sizes unless the final size is smaller.</p> <pre><code> byte[] buffer; byte[] iv = new byte[symmetricEncryptionBitSize / 8]; using (var rngCrypto = new RNGCryptoServiceProvider()) rngCrypto.GetBytes(iv); AesCryptor cryptor = new AesCryptor(); buffer = cryptor.Encrypt(chunkedFile.NextChunk(), symmetricPrivateKey, iv); </code></pre> <p>The code below is what the receiver of the file uses(not all of it, this is what pertains to the decrypting of the data). The data is being written to a file stream(<code>writer</code>).</p> <pre><code> FileMessage message = hostChannel.ReceiveFile(); moreChunks = message.FileMetaData.MoreChunks; UpdateTotalBytesTransferred(message); writer.BaseStream.Position = filePosition; byte[] decryptedStream; // Copy the message stream out to a memory stream so we can work on it afterwards. using (var memoryStream = new MemoryStream()) { message.ChunkData.CopyTo(memoryStream); decryptedStream = cryptor.Decrypt(memoryStream.ToArray(), symmetricPrivateKey, message.FileMetaData.InitializationVector); } writer.Write(decryptedStream); </code></pre> <p>By the way, in case it is needed, NextChunk is a very simple method.</p> <pre><code> public byte[] NextChunk() { if (MoreChunks) // If there are more chunks, procede with the next chunking operation, otherwise throw an exception. { byte[] buffer; using (BinaryReader reader = new BinaryReader(File.OpenRead(FilePath))) { reader.BaseStream.Position = CurrentPosition; buffer = reader.ReadBytes((int)MaximumChunkSize); } CurrentPosition += buffer.LongLength; // Sets the stream position to be used for the next call. return buffer; } else throw new InvalidOperationException("The last chunk of the file has already been returned."); } </code></pre> <p><strong>EDIT:</strong> It seems that for every chunk transferred, and thus every encryption, I am gaining 16bytes in file size. This does not happen with extremely small file sizes.</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