title: AES-GCM with BouncyCastle throws "mac check in GCM failed" when used with IV
body: <p>I'm relatively new to developing something with encryption. Right now I'm trying to write a class which encrypts and decrypts Strings using BouncyCastle with AES-GCM. I read about the things you have to consider when implementing encryption. One of them was that you should always use a randomized IV. 
  The problem is, everytime I try to initialize my Cipher with an IV it won't decrypt my text properly.<br>
  It just throws the following exception:</p>
  
  <pre><code>javax.crypto.AEADBadTagException: mac check in GCM failed
  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
  at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
  at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$AEADGenericBlockCipher.doFinal(Unknown Source)
  at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source)
  at javax.crypto.Cipher.doFinal(Cipher.java:2165)
  at BouncyCastleEX.decrypt(BouncyCastleEX.java:78)
  at BouncyCastleEX.main(BouncyCastleEX.java:43)
  </code></pre>
  
  <p>I'm using the following methods to encrypt and decrypt my data.</p>
  
  <pre><code>private static final String fallbackSalt = "ajefa6tc73t6raiw7tr63wi3r7citrawcirtcdg78o2vawri7t";
  private static final int iterations = 2000;
  private static final int keyLength = 256;
  private static final SecureRandom random = new SecureRandom();
  
  public byte[] encrypt(String plaintext, String passphrase, String salt)
          throws Exception {
      SecretKey key = generateKey(passphrase, salt);
      Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
      cipher.init(Cipher.ENCRYPT_MODE, key, generateIV(cipher),random);
      return cipher.doFinal(plaintext.getBytes());
  }
  
  public String decrypt(byte[] encrypted, String passphrase, String salt)
          throws Exception {
      SecretKey key = generateKey(passphrase, salt);
      Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
      cipher.init(Cipher.DECRYPT_MODE, key, generateIV(cipher),random);
      return new String(cipher.doFinal(encrypted));
  }
  
  private SecretKey generateKey(String passphrase, String salt)
          throws Exception {
      PBEKeySpec keySpec = new PBEKeySpec(passphrase.toCharArray(),
              salt.getBytes(), iterations, keyLength);
      SecretKeyFactory keyFactory = SecretKeyFactory
              .getInstance("PBEWITHSHA256AND256BITAES-CBC-BC");
      return keyFactory.generateSecret(keySpec);
  }
  
  private IvParameterSpec generateIV(Cipher cipher) throws Exception {
      byte[] ivBytes = new byte[cipher.getBlockSize()];
      random.nextBytes(ivBytes);
      return new IvParameterSpec(ivBytes);
  }
  </code></pre>
  
  <p>If I remove the "generateIV(cipher)" from my cipher.init(...) everything works flawlessly. But as far as I know it weakens the encryption tremendously.</p>
  
  <p>Right know I'm unable to figure out whether this is a small mistake in the code or something else I know nothing about. </p>
  
  <p>I really appreciate your help and thanks a lot!</p>