title: Decryption of a long byte array
body: <p>I would like to decrypt a long byte[], yet I can't managed to do that.</p>
  
  <p>The receiving code: I read a <code>bitmap</code> directly from the stream (works as it is supposed to), then I convert it to <code>byte[]</code> using a <code>MemoryStream</code> and then I decrypt the whole <code>byte[]</code> and then the decrypted data is supposed to turn into a <code>bitmap</code>:</p>
  
  <pre><code>Bitmap bmpTmp = BitmapFactory.DecodeStream(CommunicationHandler.GetStream());
  MemoryStream stream = new MemoryStream();
  bmpTmp.Compress(Bitmap.CompressFormat.Png, 100, stream);
  string imageString = DecryptStringFromBytes_Aes(stream.ToArray());
  </code></pre>
  
  <p>By the way, the only reason I read the stream into a <code>bitmap</code> and then convert it to a <code>byte[]</code> instead of reading the stream right into a <code>byte[]</code>, is because I have not found any function that reads a <code>NetworkStream</code> right into a <code>byte[]</code>. 
  I was wondering, how does <code>BitmapFactory.DecodeStream()</code> works? How come that this function reads the whole data? How does it know when to stop?</p>
  
  <p>The decryption code:</p>
  
  <pre><code>public static string DecryptStringFromBytes_Aes(byte[] cipherTextCombined)
      {
          string plaintext = null;
  
          // Create an Aes object with the specified key and IV.
          using (Aes aesAlg = Aes.Create())
              {
                  aesAlg.Key = key;
                  aesAlg.Padding = PaddingMode.Zeros;
                  aesAlg.Mode = CipherMode.CBC;
  
                  byte[] IV = new byte[16];
                  byte[] cipherText = new byte[cipherTextCombined.Length - IV.Length];
  
                  Array.Copy(cipherTextCombined, IV, IV.Length);
                  Array.Copy(cipherTextCombined, IV.Length, cipherText, 0, cipherText.Length);
  
                  aesAlg.IV = IV;
  
                  // Create a decryptor to perform the stream transform.
                  ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
  
                  // Create the streams used for decryption.
                  using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                      using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                          using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                              plaintext = srDecrypt.ReadToEnd(); //The error occurs here: 
  //System.ArgumentException: Offset and length were out of bounds for the array or count is 
  //greater than the number of elements from index to the end of the source collection. 
              }
  
          return plaintext.TrimEnd('\0');
      }
  </code></pre>
  
  <p>The encryption code:</p>
  
  <pre><code>def encrypt(self, message):
      message = self.pad(message)
      iv = Random.new().read(AES.block_size)
      cipher = AES.new(str.encode(self.key), AES.MODE_CBC, iv)
      return iv + cipher.encrypt(message)
  </code></pre>
  
  <p>The padding code:</p>
  
  <pre><code>def pad(s): 
      return s + b"\0" * (AES.block_size - len(s) % AES.block_size)
  </code></pre>
  
  <p>This is what I send over the NetworkStream:</p>
  
  <pre><code>import mss.tools
  
  def screenshot():
      with mss.mss() as sct:
          return sct.grab(sct.monitors[1])
  
  socket.send(mss.tools.to_png(image.rgb, image.size))
  
  </code></pre>
  
  <p>According to the error I get- <code>System.ArgumentException: Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.</code>, I think that the input is too long. This is the error stack trace: <code>at Project.LoadingImage.RunInBackground (Java.Lang.Void[] params) [0x0004d]</code>.</p>
  
  <p>Note that the methods and the system work perfectly with simple and short inputs, yet the only problem is with the image, probably because the <code>byte[]</code> input is way too big, as the error implies.</p>
  
  <p>Also, note that the decryption method returns <code>string</code> and not <code>byte[]</code> which makes it even more complicated to decode it to a <code>bitmap</code>.</p>
  
  <p>As a conclusion, 3 main questions:</p>
  
  <ol>
  <li><p>What does the error mean? How can I solve it?</p></li>
  <li><p>How does <code>BitmapFactory.DecodeStream()</code> read the whole stream? How it works?</p></li>
  <li><p>Is there any way to change the return type of the decryption function to <code>byte[]</code> from <code>string</code>?</p></li>
  </ol>