title: Why can't I encrypt multiple strings using one encryptor on MonoTouch?
body: <p>I'm using the following (trimmed-down) class to encrypt some data before sending it from an iPad app to a WCF web service.</p>
  
  <pre class="lang-cs prettyprint-override"><code>public class FlawedAlgorithm
  {
      protected static byte[] key = { 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
      protected static byte[] vector = { 13, 37, 13, 37, 13, 37, 13, 37, 13, 37, 13, 37, 13, 37, 13, 37 };
      protected ICryptoTransform encryptor, decryptor;
      protected UTF8Encoding encoder;
  
      public FlawedAlgorithm()
      {
          using (var rijndael = new RijndaelManaged())
          {
              this.encryptor = rijndael.CreateEncryptor(key, vector);
              this.decryptor = rijndael.CreateDecryptor(key, vector);
          }
  
          this.encoder = new UTF8Encoding();
      }
  
      public string Encrypt(string unencrypted)
      {
          var buffer = this.encoder.GetBytes(unencrypted);
  
          return Convert.ToBase64String(Encrypt(buffer));
      }
  
      public string Decrypt(string encrypted)
      {
          var buffer = Convert.FromBase64String(encrypted);
  
          return this.encoder.GetString(Decrypt(buffer));
      }
  
      private byte[] Encrypt(byte[] buffer)
      {
          var encryptStream = new MemoryStream();
  
          using (var cryptoStream = new CryptoStream(encryptStream, this.encryptor, CryptoStreamMode.Write))
          {
              cryptoStream.Write(buffer, 0, buffer.Length);
          }
  
          return encryptStream.ToArray();
      }
  
      private byte[] Decrypt(byte[] buffer)
      {
          var decryptStream = new MemoryStream();
  
          using (var cryptoStream = new CryptoStream(decryptStream, this.decryptor, CryptoStreamMode.Write))
          {
              cryptoStream.Write(buffer, 0, buffer.Length);
          }
  
          return decryptStream.ToArray();
      }
  }
  </code></pre>
  
  <p>When I run the following code on the server and the iPad, both print the same encrypted string.</p>
  
  <pre class="lang-cs prettyprint-override"><code>var algorithm = new FlawedAlgorithm();
  
  Console.WriteLine(algorithm.Encrypt("Some string"));
  </code></pre>
  
  <p>However, when I try to encrypt a second value, the results on the server and iPad are different.</p>
  
  <pre class="lang-cs prettyprint-override"><code>var algorithm = new FlawedAlgorithm();
  
  // The first encryption still functions correctly.
  Console.WriteLine(algorithm.Encrypt("Some string"));
  
  // This second encryption produces a different value on the iPad.
  Console.WriteLine(algorithm.Encrypt("This text is a bit longer"));
  </code></pre>
  
  <p>When I decrypt the deviating iPad result on the server, <strong>part of the decrypted string is gibberish</strong>. The encrypted results from the server decrypt correctly.</p>
  
  <p>The problem does not manifest itself if I create a new <code>FlawedAlgorithm</code> instance for each call, e.g.:</p>
  
  <pre class="lang-cs prettyprint-override"><code>// These statements produce the correct results on the iPad.
  Console.WriteLine(new FlawedAlgorithm().Encrypt("Some string"));
  Console.WriteLine(new FlawedAlgorithm().Encrypt("This text is a bit longer"));
  </code></pre>
  
  <p>This leads me to think that the problem lies somewhere in the state of the objects involved. I have inspected the <code>buffer</code> variable in the <code>Encrypt(string)</code> method and the values produced by the <code>UTF8Encoding</code> instance are correct. This implies that the <code>encryptor</code> field (or its underlying implementation) <strong>is the culprit</strong>.</p>
  
  <p>When I start varying the size of the first encrypted value, I can see changes in the result of the second encryption call. This would probably mean that some part of a stream isn't being cleared or overwritten properly. But the streams the <code>FlawedAlgorithm</code> class uses, aren't part of its state; they are recreated on each method call. And the <code>encryptor</code> object doesn't seem like the type that manages its own streams.</p>
  
  <p>Has anyone else encountered a problem similar to this? Is the <code>RijndaelManaged</code> class flawed? Or are there some stream and memory management pitfalls in MonoTouch at play here, unrelated to this cryptography example?</p>
  
  <p>P.S.: I have tested this on both the iPad and the iPad Simulator; both display this strange behavior.</p>