'javax.crypto.AEADBadTagException: Tag mismatch! when password.length >= 16

I am newbie in regards to AES encryption/decryption. I found the following nice article from Michael Remijan https://www.javacodegeeks.com/2017/12/choosing-java-cryptographic-algorithms-part-2-single-key-symmetric-encryption.html

I have tried the example tests, and it runs just fine whith smaller length passwords. However when I change the length of the message (password) string to a length >= 16 it fails with the following exception.

javax.crypto.AEADBadTagException: Tag mismatch!

at com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterMode.java:578)
at com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1049)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:985)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:847)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
at javax.crypto.Cipher.doFinal(Cipher.java:2047)

I have contacted Michael about this issue, yet he does not currently know why this behaviour occurs.

However I recently just found a fix for this but I unfortunately do not understand why. I hope you guys can help here :-)

The fix looks like this and is to be found in the encrypt method of the Aes class. The original encrypt method in the Aes class (from the article) contains the following :

public byte[] encrypt(String message, Optional<String> aad) {
......
// Add message to encrypt
c.update(message.getBytes("UTF-8"));
      
// Encrypt
byte[] encryptedBytes = c.doFinal();
//....

I changed it to this :

public byte[] encrypt(String message, Optional<String> aad) {
.....
// Add message to encrypt
// REMOVE THIS c.update(message.getBytes("UTF-8"));
        
// Encrypt
byte[] encryptedBytes = c.doFinal(message.getBytes("UTF-8"));
.....

 

and it works :-) but why ?

Thanks alot.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source