title: AES decrypt text in java, encrypted in C#
body: <p>I have to decrypt text in JAVA, encrypted in C# (AES, RijndaelManaged). </p>
  
  <p>After several days of reading and searching solutions, and a lot of stackoverflow solutions tested, i still have a problem unsolved. </p>
  
  <p>I apply C# code <a href="https://dotnetfiddle.net/0bGxEx" rel="nofollow noreferrer">here</a> (which is working) and the java code (which not fully working).</p>
  
  <p>Here is the exception from the java code:</p>
  
  <pre><code>Exception in thread "main" javax.crypto.IllegalBlockSizeException: last block incomplete in decryption
  at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source)
  at javax.crypto.Cipher.doFinal(Cipher.java:2164)
  at test.Decrypt.main(Decrypt.java:39)
  </code></pre>
  
  <h1>JAVA code</h1>
  
  <pre><code>import java.nio.charset.StandardCharsets;
  import java.security.spec.KeySpec;
  import java.util.Base64;
  
  import javax.crypto.Cipher;
  import javax.crypto.SecretKey;
  import javax.crypto.SecretKeyFactory;
  import javax.crypto.spec.IvParameterSpec;
  import javax.crypto.spec.PBEKeySpec;
  import javax.crypto.spec.SecretKeySpec;
  
  public class Decrypt {
  
  public static void main(String[] args) throws Exception {
  
      String encText = "EAAAADE2ODA2NjQya2JNN2M1ISShgi+Oi5tbsPgOz5KsCHj0";
      final String password = "KJH#$@kds32@!kjhdkftt";
      final String iv = "16806642kbM7c5!$";
      byte[] salt = new byte[] { 34, (byte) 134, (byte) 145, 12, 7, 6, (byte) 243, 63, 43, 54, 75, 65, 53, 2, 34, 54,
              45, 67, 64, 64, 32, (byte) 213 };
  
      SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
      KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 1000, 256);
      SecretKey tmp = factory.generateSecret(spec);
  
      SecretKeySpec secret = new SecretKeySpec(tmp.getEncoded(), "AES");
      IvParameterSpec ivs = new IvParameterSpec(iv.getBytes(StandardCharsets.US_ASCII));
  
      System.out.println("Key:" + Base64.getEncoder().encodeToString(secret.getEncoded()));
      System.out.println("IV:" + Base64.getEncoder().encodeToString(ivs.getIV()));
  
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
      cipher.init(Cipher.DECRYPT_MODE, secret, ivs);
  
      byte [] decodedText = Base64.getDecoder().decode(encText);
  
      String plaintext = new String(cipher.doFinal(decodedText), "UTF-8");
      System.out.println(plaintext);
    }
  }
  </code></pre>
  
  <h1>C# code</h1>
  
  <pre><code>using System;
  using System.IO;
  using System.Security.Cryptography;
  using System.Text;
  
  namespace Test
  {
  public class EncriptionHelper
  {   
          public static void Main()
          {
              var cleanTxt = "8212093345";
              var encTxt = "EAAAADE2ODA2NjQya2JNN2M1ISShgi+Oi5tbsPgOz5KsCHj0";
              var secret = "KJH#$@kds32@!kjhdkftt";
  
              var xtxt =  EncryptStringAES(cleanTxt, secret);             
              var txt =   DecryptStringAES(encTxt, secret);
  
              Console.WriteLine(txt);
              Console.WriteLine(xtxt);
          }
  
      private static byte[] vector = Encoding.ASCII.GetBytes("16806642kbM7c5!$");
      private static byte[] salt = new byte[] { 34, 134, 145, 12, 7, 6, 243, 63, 43, 54, 75, 65, 53, 2, 34, 54, 45, 67, 64, 64, 32, 213 };
  
      /// &lt;summary&gt;
      /// Encrypt the given string using AES.  The string can be decrypted using 
      /// DecryptStringAES().  The sharedSecret parameters must match.
      public static string EncryptStringAES(string text, string sharedSecret)
      {
          if (string.IsNullOrEmpty(text))
          {
              throw new ArgumentNullException("Text is null or empty");
          }
  
          if (string.IsNullOrEmpty(sharedSecret))
          {
              throw new ArgumentNullException("Secret is null or empty");
          }
  
          if (salt == null || salt.Length == 0)
          {
              throw new ArgumentNullException("Salt is null or empty");
          }
  
          string outStr = null;
          RijndaelManaged aesAlg = null;
          try
          {
              Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, salt);
  
              aesAlg = new RijndaelManaged();
              aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
              aesAlg.IV = vector;
  
              ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
              using (MemoryStream msEncrypt = new MemoryStream())
              {
                  msEncrypt.Write(BitConverter.GetBytes(aesAlg.IV.Length), 0, sizeof(int));
                  msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length);
                  using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                  {
                      using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                      {
                          swEncrypt.Write(text);
                      }
                  }
                  outStr = Convert.ToBase64String(msEncrypt.ToArray());
              }
          }
          finally
          {
              // Clear the RijndaelManaged object.
              if (aesAlg != null)
                  aesAlg.Clear();
          }
  
          // Return the encrypted bytes from the memory stream.
          return outStr;
      }
  
      /// &lt;summary&gt;
      /// Decrypt the given string.  Assumes the string was encrypted using 
      /// EncryptStringAES(), using an identical sharedSecret.
      /// &lt;/summary&gt;
      public static string DecryptStringAES(string cipherText, string sharedSecret)
      {
          if (string.IsNullOrEmpty(cipherText))
          {
              throw new ArgumentNullException("Text is null or empty");
          }
  
          if (string.IsNullOrEmpty(sharedSecret))
          {
              throw new ArgumentNullException("Secret is null or empty");
          }
  
          if (salt == null || salt.Length == 0)
          {
              throw new ArgumentNullException("Salt is null or empty");
          }
  
          RijndaelManaged aesAlg = null;
          string result = null;
  
          try
          {
              Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, salt);
              byte[] bytes = Convert.FromBase64String(cipherText);
              using (MemoryStream msDecrypt = new MemoryStream(bytes))
              {
                  aesAlg = new RijndaelManaged();
                  aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
                  aesAlg.IV = ReadByteArray(msDecrypt);
  
                  Console.WriteLine("KEY: "+ Convert.ToBase64String(aesAlg.Key));
                  Console.WriteLine("IV: "+ Convert.ToBase64String(aesAlg.IV));
  
  
                  ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
                  using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                  {
                      using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                      {
                          result = srDecrypt.ReadToEnd();
                      }
                  }
              }
          }
          finally
          {
              // Clear the RijndaelManaged object.
              if (aesAlg != null)
                  aesAlg.Clear();
          }
  
          return result;
      }
  
      private static byte[] ReadByteArray(Stream s)
      {
          byte[] rawLength = new byte[sizeof(int)];
          if (s.Read(rawLength, 0, rawLength.Length) != rawLength.Length)
          {
              throw new SystemException("Stream did not contain properly formatted byte array");
          }
  
          byte[] buffer = new byte[BitConverter.ToInt32(rawLength, 0)];
          if (s.Read(buffer, 0, buffer.Length) != buffer.Length)
          {
              throw new SystemException("Did not read byte array properly");
          }
          return buffer;
      }
    }
   }
  </code></pre>