title: Tag mismatch error in AES-256-GCM Decryption using Java
body: <p>I have the following function written in Javascript for encryption using aes-256-gcm:</p>
  
  <pre><code>encrypt: function (text, masterkey){
      try {
          // random initialization vector
          var iv = crypto.randomBytes(12);
  
          // random salt
          var salt = crypto.randomBytes(64);
  
          // derive key: 32 byte key length - in assumption the masterkey is a cryptographic and NOT a password there is no need for
          // a large number of iterations. It may can replaced by HKDF
          var key = crypto.pbkdf2Sync(masterkey, salt, 2145, 32, 'sha512');
  
          // AES 256 GCM Mode
          var cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
  
          // encrypt the given text
          var encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()]);
  
          // extract the auth tag
          var tag = cipher.getAuthTag();
  
          // generate output
          return Buffer.concat([salt, iv, tag, encrypted]).toString('base64');
  
      }catch(e){
      }
  
      // error
      return null;
  }
  </code></pre>
  
  <p>The encrypted text by the above function is successfully decrypted back using the following function:</p>
  
  <pre><code>decrypt: function (data, masterkey){
      try {
          // base64 decoding
          var bData = new Buffer(data, 'base64');
          var salt = bData.slice(0, 64);
          var iv = bData.slice(64, 76);
          var tag = bData.slice(76, 92);
          var text = bData.slice(92);
  
          // derive key using; 32 byte key length
          var key = crypto.pbkdf2Sync(masterkey, salt , 2145, 32, 'sha512');
          // AES 256 GCM Mode
          var decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
          decipher.setAuthTag(tag);
  
          // decrypt the given text
          var decrypted = decipher.update(text, 'binary', 'utf8') + decipher.final('utf8');
  
          return decrypted;
  
      }catch(e){
      }
  
      // error
      return null;
  }
  </code></pre>
  
  <p>Now, I need a method in Java for decryption which is the equivalent of the above Javascript decrypt function. Following is the Java code I have written for decryption:</p>
  
  <pre><code>public void decrypt(byte[] nkb, String crKey){
      //nkb is byte array formed by Base64 decoding of 'data' variable in the Javascript code
      //crKey corresponds to the 'masterkey' variable
  
      byte[] salt = Arrays.copyOfRange(nkb, 0, 64);
      byte[] iv = Arrays.copyOfRange(nkb, 64, 76);
      byte[] tag = Arrays.copyOfRange(nkb, 76, 92);
      byte[] text = Arrays.copyOfRange(nkb, 92, nkb.length);
  
      PBEKeySpec ks = new PBEKeySpec(crKey.toCharArray(), salt, iterations, 256);
      SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
      SecretKey pbeKey = skf.generateSecret(ks);
  
      byte[] decrypted = decrypt(iv, pbeKey.getEncoded(), text, tag);
  }
      public static byte[] decrypt(byte[] ivBytes, byte[] keyBytes, byte[] textBytes, byte[] tagBytes)
          throws java.io.UnsupportedEncodingException,
          NoSuchAlgorithmException,
          NoSuchPaddingException,
          InvalidKeyException,
          InvalidAlgorithmParameterException,
          IllegalBlockSizeException,
          BadPaddingException,
          NoSuchProviderException {
  
          GCMParameterSpec ivSpec = new GCMParameterSpec(tagBytes.length*Byte.SIZE, ivBytes);
  
          SecretKeySpec newKey = new SecretKeySpec(keyBytes, "AES");
  
          Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
          cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec);
          return cipher.doFinal(textBytes); //getting tag mismatch error here
      }
  </code></pre>
  
  <p>As I have commented in the above code, I get a Tag mismatch error in the last line. I would appreciate some help in finding out what I am doing wrong.</p>
  
  <p>I have error in this line code:</p>
  
  <pre><code>cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec)
  java.security.InvalidKeyException: Illegal key size
  at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1039)
  at javax.crypto.Cipher.implInit(Cipher.java:805)
  at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
  at javax.crypto.Cipher.init(Cipher.java:1396)
  at javax.crypto.Cipher.init(Cipher.java:1327)
  at com.micropro.namwebservice.utils.CryptoUtils.decrypt(CryptoUtils.java:93)
  at com.micropro.namwebservice.utils.CryptoUtils.decrypt(CryptoUtils.java:82)
  </code></pre>