title: AesCryptoServiceProvider "The input data is not a complete block"
body: <p>I wrote two programs in C#. One does the encryption, and the other one does the decryption. The decryption program throws exception of "The input data is not a complete block" with data from the encryption program. However the decryption program works fine with the encrypted data from a Unix encryption program, using PKCS5_PBKDF2_HMAC_SHA1().</p>
  
  <p>Encrypted data is base 64 encoded, and saved in a text file. The first 8 bytes is a salt, the next 16 bytes is an IV, and the rest is the application text.</p>
  
  <p>I would appreciate very much if anyone could help.</p>
  
  <pre><code>    public static string DecryptText(string cipherData)
      {
          if (string.IsNullOrEmpty(_passwd))
              return null;
  
          var decodedBytes = Convert.FromBase64String(cipherData);
  
          // First 8 bytes contain the salt used for key derivation. Use the password from the passwd.dat
          // file and the salt to derive the key used to encode the credential.
          //
          var salt = new byte[8];
          Buffer.BlockCopy(decodedBytes, 0, salt, 0, 8);
          var derivedBytes = new Rfc2898DeriveBytes(_passwd, salt, 1000);
          var key = derivedBytes.GetBytes(32);
  
          // Next 16 bytes contain the initialization vector used to encrypt
          //
          var ivBytes = new byte[16];
          Buffer.BlockCopy(decodedBytes, 8, ivBytes, 0, ivBytes.Length);
  
          // Remaining bytes contain the credential cipher text
          //
          var cipherBytes = new byte[decodedBytes.Length - 8 - 16];
          Buffer.BlockCopy(decodedBytes, 8 + 16, cipherBytes, 0, cipherBytes.Length);
  
          string decryptedData = null;
          try
          {
              using (var aes = new AesCryptoServiceProvider())
              {
                  aes.Key = key;
                  aes.IV = ivBytes;
  
                  using (var ms = new MemoryStream())
                  {
                      using (var cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
                      {
                          cs.Write(cipherBytes, 0, cipherBytes.Length);
                          cs.Close();
                      }
  
                      decryptedData = Encoding.UTF8.GetString(ms.ToArray());
                  }
              }
          }
          catch (Exception ex)
          {
              Console.Write("Caught exception while decryption: {0}: ", ex.Message);
          }
  
          return decryptedData;
      }
  
      public static string EncryptText(string plainData)
      {
          if (string.IsNullOrEmpty(_passwd))
              return null;
  
          var rfc2898db = new Rfc2898DeriveBytes(_passwd, 8, 1000);
          byte[] salt = new byte[8];
          Buffer.BlockCopy(rfc2898db.Salt, 0, salt, 0, 8);
          byte[] key = new byte[32];
          Buffer.BlockCopy(rfc2898db.GetBytes(32), 0, key, 0, 32);
  
          string cipherData;
  
          try
          {
              var aes = new AesCryptoServiceProvider
              {
                  Key = key,
                  KeySize = 256,
                  BlockSize = 128,
                  Mode = CipherMode.CBC,
                  Padding = PaddingMode.PKCS7
              };
              aes.GenerateIV();
  
              byte[] encrypted;
              using (var ms = new MemoryStream())
              {
                  using (var cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
                  {
                      ms.Write(aes.IV, 0, aes.IV.Length);
                      ms.Write(salt, 0, 8);
                      cs.Write(Encoding.UTF8.GetBytes(plainData), 0, plainData.Length);
                      cs.Close();
                  }
  
                  encrypted = ms.ToArray();
              }
  
              byte[] encryptedBytes = new byte[SaltLength + IvLength + encrypted.Length];
              Buffer.BlockCopy(salt, 0, encryptedBytes, 0, SaltLength);
              Buffer.BlockCopy(aes.IV, 0, encryptedBytes, SaltLength, IvLength);
              Buffer.BlockCopy(encrypted, 0, encryptedBytes, SaltLength + IvLength, encrypted.Length);
  
              cipherData = Convert.ToBase64String(encryptedBytes);
          }
          catch (Exception ex)
          {
              Console.Write("Caught exception while encryption: {0}", ex.Message);
              return null;
          }
  
          return cipherData;
      }
  </code></pre>