title: GCM encryption built in MAC check failure
body: <p>I am trying to write a couple functions that can encrypt and decrypt text using AES/GCM encryption in conjunction with PBKDF2 key generation. I am transitioning my code from CTR (SIC) encryption, and the MAC check failure is killing me when all else is working.</p>
  <pre><code>fun encryptAESBasic(input: String, password: String): String {
      val masterpw = getKey(password)
      val random = SecureRandom()
      val salt = ByteArray(16)
      random.nextBytes(salt)
  
      val factory: SecretKeyFactory = SecretKeyFactory.getInstance(&quot;PBKDF2WithHmacSHA1&quot;)
      val spec: KeySpec = PBEKeySpec(masterpw.toString().toCharArray(), salt, 100, 256)
      val tmp: SecretKey = factory.generateSecret(spec)
      val cipher = Cipher.getInstance(&quot;AES/CTR/NoPadding&quot;)
  
      val iv = ByteArray(16)
      SecureRandom().nextBytes(iv)
  
      cipher.init(Cipher.ENCRYPT_MODE, tmp, IvParameterSpec(iv))
      val cipherText: ByteArray = cipher.doFinal(input.toByteArray(Charset.forName(&quot;UTF-8&quot;)))
  
      val ivstring: String = Base64.encodeToString(iv, Base64.NO_WRAP)
      val saltystring: String = Base64.encodeToString(salt, Base64.NO_WRAP)
      val cipherstring: String = Base64.encodeToString(cipherText, Base64.NO_WRAP)
      val returnstring: String = ivstring + &quot;-&quot; + saltystring + &quot;-&quot; + cipherstring
  
      return returnstring
  }
  
  fun decryptAESBasic(text: String, password: String): String {
  
      val arr = text.split(&quot;-&quot;)
      val iv = Base64.decode(arr[0].toByteArray(Charset.forName(&quot;UTF-8&quot;)), Base64.NO_WRAP)
      val salt = Base64.decode(arr[1].toByteArray(Charset.forName(&quot;UTF-8&quot;)), Base64.NO_WRAP)
      val data = arr[2].toByteArray(Charset.forName(&quot;UTF-8&quot;))
  
      val masterpw = getKey(password)
      val factory: SecretKeyFactory = SecretKeyFactory.getInstance(&quot;PBKDF2WithHmacSHA1&quot;)
      val spec: KeySpec = PBEKeySpec(masterpw.toString().toCharArray(), salt, 100, 256)
      val tmp: SecretKey = factory.generateSecret(spec)
      val key: ByteArray = tmp.getEncoded()
  
      val cipher = Cipher.getInstance(&quot;AES/CTR/NoPadding&quot;)
      cipher.init(Cipher.DECRYPT_MODE, tmp, IvParameterSpec(iv))
      val credential: ByteArray = cipher.doFinal(Base64.decode(data, Base64.NO_WRAP))
      return credential.toString(Charset.forName(&quot;UTF-8&quot;))
  }
  
  fun getKey(masterPass: String): ByteArray {
      return masterPass.padEnd(32, '.').toByteArray(Charset.forName(&quot;UTF-8&quot;))
  }
  
  </code></pre>
  <p>Again, this code works, but I would like to change it from CTR to GCM but every time that I do I am met with a &quot;mac check in GCM failed&quot; error. Any help explaining how/why this is happening would be tremendously appreciated.</p>
  <pre><code>E/AndroidRuntime( 6461): Caused by: javax.crypto.AEADBadTagException: mac check in GCM failed
  E/AndroidRuntime( 6461):        at java.lang.reflect.Constructor.newInstance0(Native Method)
  E/AndroidRuntime( 6461):        at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
  E/AndroidRuntime( 6461):        at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$AEADGenericBlockCipher.doFinal(BaseBlockCipher.java:1485)
  E/AndroidRuntime( 6461):        at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(BaseBlockCipher.java:1217)
  E/AndroidRuntime( 6461):        at javax.crypto.Cipher.doFinal(Cipher.java:2055)
  E/AndroidRuntime( 6461):        at design.codeux.autofill_service.FlutterMyAutofillServiceKt.decryptAESBasic(FlutterMyAutofillService.kt:1003)
  </code></pre>