title: C#.net to Java- Encryption and decryption using AES with Password
body: <p>I am trying to reproduce the following encryption/decryption algorithm in Java, but I can't find the alternatives for multiple methods such as Rfc2898DeriveBytes() and RijndaelManaged(). How do I do this?</p>
  <pre class="lang-cs prettyprint-override"><code>using System;
  using System.Collections.Generic;
  using System.IO;
  using System.Linq;
  using System.Security.Cryptography;
  using System.Text;
  
  namespace CryptingTest
  {   
      public static class StringCipher
      {
          // This constant is used to determine the keysize of the encryption algorithm in bits.
          // We divide this by 8 within the code below to get the equivalent number of bytes.
          private const int Keysize = 128;
  
          // This constant determines the number of iterations for the password bytes generation function.
          private const int DerivationIterations = 1000;
  
          public static string Encrypt(string plainText, string passPhrase)
          {
              // Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
              // so that the same Salt and IV values can be used when decrypting.  
              var saltStringBytes = Generate128BitsOfRandomEntropy();
              var ivStringBytes = Generate128BitsOfRandomEntropy();
              var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
              using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
              {
                  var keyBytes = password.GetBytes(Keysize / 8);
                  using (var symmetricKey = new RijndaelManaged())
                  {
                      symmetricKey.BlockSize = 128;
                      symmetricKey.Mode = CipherMode.CBC;
                      symmetricKey.Padding = PaddingMode.PKCS7;
                      using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes))
                      {
                          using (var memoryStream = new MemoryStream())
                          {
                              using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                              {
                                  cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                                  cryptoStream.FlushFinalBlock();
                                  // Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
                                  var cipherTextBytes = saltStringBytes;
                                  cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
                                  cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
                                  memoryStream.Close();
                                  cryptoStream.Close();
                                  return Convert.ToBase64String(cipherTextBytes);
                              }
                          }
                      }
                  }
              }
          }
  
          public static string Decrypt(string cipherText, string passPhrase)
          {
              // Get the complete stream of bytes that represent:
              // [32 bytes of Salt] + [16 bytes of IV] + [n bytes of CipherText]
              var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
              // Get the saltbytes by extracting the first 16 bytes from the supplied cipherText bytes.
              var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
              // Get the IV bytes by extracting the next 16 bytes from the supplied cipherText bytes.
              var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
              // Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
              var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
  
              using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
              {
                  var keyBytes = password.GetBytes(Keysize / 8);
                  using (var symmetricKey = new RijndaelManaged())
                  {
                      symmetricKey.BlockSize = 128;
                      symmetricKey.Mode = CipherMode.CBC;
                      symmetricKey.Padding = PaddingMode.PKCS7;
                      using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
                      {
                          using (var memoryStream = new MemoryStream(cipherTextBytes))
                          {
                              using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                              {
                                  var plainTextBytes = new byte[cipherTextBytes.Length];
                                  var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                                  memoryStream.Close();
                                  cryptoStream.Close();
                                  return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                              }
                          }
                      }
                  }
              }
          }
  
          private static byte[] Generate128BitsOfRandomEntropy()
          {
              var randomBytes = new byte[16]; // 16 Bytes will give us 128 bits.
              using (var rngCsp = new RNGCryptoServiceProvider())
              {
                  // Fill the array with cryptographically secure random bytes.
                  rngCsp.GetBytes(randomBytes);
              }
              return randomBytes;
          }
      }
  }
  </code></pre>
  <p>Any help would be really appreciated.</p>
  <p>Here's a code snippet from what I tried so far but it's still off:</p>
  <pre class="lang-java prettyprint-override"><code>private static byte[] Generate128BitsOfRandomEntropy()
  {
      var randomBytes = new byte[16]; // 16 Bytes will give us 128 bits.
         
      SecureRandom rngCsp = new SecureRandom();
      // Fill the array with cryptographically secure random bytes.
      rngCsp.nextBytes(randomBytes);
          
      return randomBytes;
  }
      
  public static String encrypt(String plainText, String passPhrase) 
  {
      try
      {
          var saltStringBytes = Generate128BitsOfRandomEntropy();
          SecretKeyFactory factory = SecretKeyFactory.getInstance(&quot;PBKDF2WithHmacSHA1&quot;);
          PBEKeySpec pbeKeySpec = new PBEKeySpec(passPhrase.toCharArray(), saltStringBytes, 1000, 384);
          Key secretKey = factory.generateSecret(pbeKeySpec);
          byte[] key = new byte[16];
          byte[] iv = new byte[16];
          System.arraycopy(secretKey.getEncoded(), 0, key, 0, 16);
          System.arraycopy(secretKey.getEncoded(), 16, iv, 0, 16);
  
          SecretKeySpec secret = new SecretKeySpec(key, &quot;AES&quot;);
          AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
          Cipher cipher = Cipher.getInstance(&quot;AES/CBC/PKCS5Padding&quot;);
          cipher.init(Cipher.ENCRYPT_MODE, secret, ivSpec);
  
          return Base64.getEncoder().encodeToString(cipher.doFinal(plainText.getBytes(&quot;UTF-8&quot;)));
      } 
      catch (Exception e) 
      {
          System.out.println(&quot;Error while encrypting: &quot; + e.toString());
      }
      return null;
  }
  </code></pre>