title: Padding in AES CBC
body: <p>I am trying to test CBC with Random IV using (128-bit AES) in C#.</p>
  
  <p>In my question to solve, I have 12-byte input message. The condition is that if PlainText is less than block-size (16-bytes) the padding to be used starts with 0x01 and then upto 6 0x00. </p>
  
  <p><strong>Example:</strong></p>
  
  <pre><code>in ASCII PT     = Pay Bob 100%
  
  in hex PT       = 50 61 79 20 42 6f 62 20 31 30 30 24
  
  PT with Padding = 50 61 79 20 42 6f 62 20 31 30 30 24 01 00 00 00
  </code></pre>
  
  <p>I don't seem to be able to find this <strong>PaddingMode</strong> in <strong>RijndaelManaged</strong>.</p>
  
  <p>Can any one suggest me how to do the following? </p>
  
  <ul>
  <li>Variable Length padding  </li>
  </ul>
  
  <p><strong>EDIT:</strong></p>
  
  <pre><code>public class CBC
  {
      public CBC()
      {
  
      }
  
      private static readonly byte[] SALT = new byte[]
          {0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c};
  
      public static byte[] EncryptCBC(string plainText, string passPhrase, PaddingMode paddingMode )
      {
          byte[] result;
          using (RijndaelManaged cryptoProvider = new RijndaelManaged())
          {
              Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(passPhrase, SALT);
              cryptoProvider.Mode = CipherMode.CBC;
              cryptoProvider.GenerateIV(); // generate random IV
  
              cryptoProvider.Padding = paddingMode;
  
              cryptoProvider.Key = derivedKey.GetBytes(cryptoProvider.KeySize / 8);
  
              using (MemoryStream msEncrypt = new MemoryStream())
              {
                  using (ICryptoTransform encryptor = cryptoProvider.CreateEncryptor(cryptoProvider.Key, cryptoProvider.IV))
                  {
                      using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                      {
                          using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                          {
                              swEncrypt.Write(plainText);
                          }
                      }
                  }
                  // concatenate iv to ciphertext
                  result = cryptoProvider.IV.Concat(msEncrypt.ToArray()).ToArray();
              }
              cryptoProvider.Clear();
          }
          return result;
      }
  
      public static string DecryptCBC(byte[] cipherTextBytes, string passPhrase, PaddingMode paddingMode)
      {
          string result = null;
          using (RijndaelManaged cryptoProvider = new RijndaelManaged())
          {
              Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(passPhrase, SALT);
              cryptoProvider.Mode = CipherMode.CBC;
              // take the iv off the beginning of the ciphertext message
              cryptoProvider.IV = cipherTextBytes.Take(cryptoProvider.BlockSize / 8).ToArray();
  
  
              cryptoProvider.Padding = paddingMode;//PaddingMode.ANSIX923;
  
  
  
              cryptoProvider.Key = derivedKey.GetBytes(cryptoProvider.KeySize / 8);
  
              using (MemoryStream msEncrypt = new MemoryStream(cipherTextBytes.Skip(cryptoProvider.BlockSize / 8).ToArray())) // skip the IV bytes
              {
                  using (ICryptoTransform encryptor = cryptoProvider.CreateDecryptor(cryptoProvider.Key, cryptoProvider.IV))
                  {
                      using (CryptoStream cryptoStream = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Read))
                      {
                          byte[] plainTextBytes = new byte[cipherTextBytes.Length - cryptoProvider.BlockSize / 8];
                          int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
  
                          result = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                          cryptoStream.Close();
                      }
                  }
              }
  
              cryptoProvider.Clear();
          }
          return result;
      }
  
  }
  </code></pre>
  
  <p><strong>My Padding function</strong></p>
  
  <pre><code>        private byte[] PaddPlainTextBytes(byte[] plainTextBytes )
      {
          byte[] padding = utils.HexToBytes("01000000");
          MemoryStream s = new MemoryStream();
  
          s.Write(plainTextBytes, 0, plainTextBytes.Length);
          s.Write(padding, 0, padding.Length);
  
          byte[] paddedPt = s.ToArray();
  
          return paddedPt;
      }
  </code></pre>
  
  <p><strong>Method to test my CBC</strong></p>
  
  <pre><code>        private void btnTestCBC_Click(object sender, EventArgs e)
      {
          string plainText = "Pay Bob 100%";
  
          string passPhrase = "Thisismypassphrase";
          ShowMessage(@"Plain Text = " + plainText);
  
          byte[] pBytes = PaddPlainTextBytes(Encoding.ASCII.GetBytes(plainText));
  
          string message = Encoding.ASCII.GetString(pBytes);
  
          byte[] encryptedBytes = CBC.EncryptCBC(plainText: message, passPhrase: passPhrase, paddingMode: PaddingMode.None);
  
          ShowMessage("Encrypted String = " + Encoding.ASCII.GetString(encryptedBytes));
          ShowMessage("Encrypted HEX = " + utils.BytesToHex(encryptedBytes));
  
  
          string decryptedString = CBC.DecryptCBC(encryptedBytes, passPhrase, PaddingMode.None);
          ShowMessage("Deccrypted String = " + decryptedString);
      }
  </code></pre>