title: javax.crypto.AEADBadTagException: mac check in GCM failed
body: <p>I'm developing Android client. What we have:</p>
  <ol>
  <li>Server ecnrypts data by AES algorithm with GCM;</li>
  <li>Server sends it to client by REST API;</li>
  <li>Client has to decrypt data and display it.</li>
  </ol>
  <p>I stuck on 3 step. My question is how to decrypt arrived data. This is what I tried already:</p>
  <pre><code>class PrivateInfoDecrypter {
  
      companion object {
          const val SECRET_KEY = &quot;secret_key&quot;
      }
  
      private val bytes = ByteArray(16)
      private val gcmParameterSpec: GCMParameterSpec = GCMParameterSpec(128, bytes)
  
      fun decrypt(input: String, smsCode: String): String {
          val keySpec = generateKey(smsCode)
  
          val cipher: Cipher = Cipher.getInstance(&quot;AES/GCM/NoPadding&quot;)
          cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec)
  
          val original = cipher.doFinal(input.toByteArray())
  
          return String(original)
      }
  
      private fun generateKey(smsCode: String): SecretKeySpec {
          val spec: KeySpec = PBEKeySpec(smsCode.toCharArray(), SECRET_KEY.encodeToByteArray(), 65536, 256)
          val f: SecretKeyFactory = SecretKeyFactory.getInstance(&quot;PBKDF2WithHmacSHA1&quot;)
          val key: SecretKey = f.generateSecret(spec)
  
          return SecretKeySpec(key.encoded, &quot;AES&quot;)
      }
  
  }
  </code></pre>
  <p>I get this error in logcat:</p>
  <pre><code>E/Whoops: javax.crypto.AEADBadTagException: mac check in GCM failed
      at java.lang.reflect.Constructor.newInstance0(Native Method)
      at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
      at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$AEADGenericBlockCipher.doFinal(BaseBlockCipher.java:1367)
      at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(BaseBlockCipher.java:1100)
      at javax.crypto.Cipher.doFinal(Cipher.java:2056)
  </code></pre>
  <p>Encryption side: (server side code)</p>
  <pre><code>    private static final byte[] bytes = new byte[16];
      static final GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, bytes);
  
      String encrypt(String input) throws Exception {
          KeySpec spec = new PBEKeySpec(otpCode.toCharArray(), secretKey.getEncoded(), 65536, 256);
          SecretKeyFactory f = SecretKeyFactory.getInstance(&quot;PBKDF2WithHmacSHA1&quot;);
          byte[] key = f.generateSecret(spec).getEncoded();
          Cipher cipher = Cipher.getInstance(&quot;AES/GCM/NoPadding&quot;);
          SecretKeySpec keySpec = new SecretKeySpec(key, &quot;AES&quot;);
          cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);
          var salted = getPseudoSaltedValue(val);
          return new String(Hex.encode(cipher.doFinal(salted.getBytes())));
      }
  </code></pre>