Tag Archives: Encryption and Decryption

[Solved] javax.crypto.AEADBadTagException: Tag mismatch


AEADBadTagException is subclass of BadPaddingException. It’s occurred when a Cipher unable to verify the authentication tag. It’s occurred when Cipher is AEAD i.e GCM/CCM mode.

public class AEADBadTagException extends BadPaddingException

Constructor

  • AEADBadTagException(): Constructs a default constructor of AEADBadTagException with no detail message.
  • AEADBadTagException(String msg): Constructs a message constructor of AEADBadTagException with the specified detail message.

Exception

Here is a complete example of encryption and decryption based on algorithm AES/GCM/NoPadding but having an issue because of IV value which is used for authentication.

import java.security.SecureRandom;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;<span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span>
/**
* example for plain text encryption and decryption by using Java AES 256 GCM Encryption Algorithm
*/
public class AES_GCM_Example
{
        static String plainText = "facing Issues on IT  (Learn from Others Experience)";
           public static final int AES_KEY_SIZE = 256;
           public static final int GCM_IV_LENGTH = 12;
           public static final int GCM_TAG_LENGTH = 16;

           public static void main(String[] args) throws Exception
           {
               KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
               keyGenerator.init(AES_KEY_SIZE);

               // Generate Key
               SecretKey key = keyGenerator.generateKey();

               byte[] IV = new byte[GCM_IV_LENGTH];
               SecureRandom random = new SecureRandom();
               random.nextBytes(IV);

               System.out.println("Original Text : " + plainText);

               byte[] cipherText = encrypt(plainText.getBytes(), key, IV);
               System.out.println("Encrypted Text : " + Base64.getEncoder().encodeToString(cipherText));

               String decryptedText = decrypt(cipherText, key, IV);
               System.out.println("DeCrypted Text : " + decryptedText);
           }

           public static byte[] encrypt(byte[] plaintext, SecretKey key, byte[] IV) throws Exception
           {
               // Get Cipher Instance for selected algorithm
               Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

               // Create SecretKeySpec for key
               SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");

               // Create GCMParameterSpec for key
               GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);

               // Initialize Cipher for ENCRYPT_MODE for encrypt plaintext
               cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);

               // Perform Encryption
               byte[] cipherText = cipher.doFinal(plaintext);

               return cipherText;
           }

           public static String decrypt(byte[] cipherText, SecretKey key, byte[] IV) throws Exception
           {
               // Get Cipher Instance based on selective AES algorithm
               Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

               // Create SecretKeySpec for key
               SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");

               // Create GCMParameterSpec for key
               //IV = new byte[GCM_IV_LENGTH]; //here is issue

               GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);

               // Initialize Cipher for DECRYPT_MODE to in plain text
               cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);

               // Perform Decryption on encrypted text
               byte[] decryptedText = cipher.doFinal(cipherText);

               return new String(decryptedText);
           }

       }

Output


Original Text : facing Issues on IT  (Learn from Others Experience)
Encrypted Text : AxboQXVKKPMm05cRaslMuxDl8IK77OLgG2ddnVSKzQUVQEXL/Xic+OHN/8ixbrFbvSrytStUWBsYQyXIWLQB22+0sg==
Exception in thread "main" javax.crypto.AEADBadTagException: Tag mismatch!
       at com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterMode.java:524)
       at com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1023)
       at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:960)
       at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
       at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
       at javax.crypto.Cipher.doFinal(Cipher.java:2121)
       at enc_dec.AES_GCM_Example.decrypt(AES_GCM_Example.java:84)
       at enc_dec.AES_GCM_Example.main(AES_GCM_Example.java:41)

Solution

Here is an issue on decryption while changing the value of IV as in line by creating new byte array which is different from the value passed in encryption that’s why encryption and decryption authentication get failed.

As a solution specific this issue comment line 68 and it will return output as below.


Original Text : facing Issues on IT  (Learn from Others Experience)
Encrypted Text : faSkDrA737VyiocRk1n5arFGaO5r7GDN6xFmz7hjZppkN0y8sgcj9N5iqaZ2+gbRowli5Ocfm1sQB2qL+nEVIzsWVg==
DeCrypted Text : facing Issues on IT  (Learn from Others Experience)

References

[Solved] javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher


Generally this exception happen while having some encrypted character which where used for URL parameter encryption.

Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
	at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:936)
	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:2165)
	at security.EncryptionDecryptionURLParam.main(EncryptionDecryptionURLParam.java:51)

Solution :

Use below line of statements. Follow example below for more detail.

Not Use :

 byte[] decryptedPassword = cipher.doFinal(decodeStr.getBytes());

Use:

byte[] base64decodedTokenArr = Base64.decodeBase64(decodeStr.getBytes());
byte[] decryptedPassword = cipher.doFinal(base64decodedTokenArr);

Example :

Issues Solution

For more other JAVA/JDBC issues solution follow link JAVA/JDBC Issues.

[Solved] Exception java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/ECB/PKCS7Padding


Java 8 doesn’t support provider “AES/ECB/PKCS7Padding” .

Exception :

Exception in thread "main" java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/ECB/PKCS7Padding
	at javax.crypto.Cipher.getInstance(Cipher.java:540)
	at security.EncryptionDecryptionURLParam.main(EncryptionDecryptionURLParam.java:31)

Solution :

Java 8 doesn’t support provider “AES/ECB/PKCS7Padding” use provider as “AES/ECB/PKCS5Padding” as used in given example for Encryption and Decryption.

Examples:

 

Issues Solution

For more other JAVA/JDBC issues solution follow link JAVA/JDBC Issues.

How to do Encryption and Decryption for plain text/password in JAVA


Java code for Encryption and Decryption of plain text. In below code encrypting plain text encrypted by using Key by algorithm “AES/ECB/PKCS5Padding“ and Decryption again in plain text.

Pre-Requisite :

  • Java 7 or 8
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class EncryptionDecryption {

	public static void main(String[] args) throws Exception {
	    byte[] input = "facingissuesonit.com".getBytes();
	    byte[] keyBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
	        0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };

	    SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");

	    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

	    System.out.println(new String(input));

	    // Encryption pass
	    cipher.init(Cipher.ENCRYPT_MODE, key);

	    byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
	    int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
	    ctLength += cipher.doFinal(cipherText, ctLength);
	    System.out.println(new String(cipherText));
	    System.out.println(ctLength);

	    // Decryption pass
	    cipher.init(Cipher.DECRYPT_MODE, key);
	    byte[] plainText = new byte[cipher.getOutputSize(ctLength)];
	    int ptLength = cipher.update(cipherText, 0, ctLength, plainText, 0);
	    ptLength += cipher.doFinal(plainText, ptLength);
	    System.out.println(new String(plainText));
	    System.out.println(ptLength);
	  }

}

More Sample Code

For more JAVA and JDBC codes follow below links

 

JAVA Encryption and Decryption of URL Parameter


Java code for Encryption and Decryption of URL parameters.  In below code encrypting parameter as passed as token which is having (Fixed Text + Time stamp and Session ID) and encrypted by using Key by algorithm “AES/ECB/PKCS5Padding“.

Pre-requisite :

  • JAVA 8
  • Common-Codec-1.8.jar
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
public class EncryptionDecryptionURLParam {
	public static final String FORMAT = "yyyy-MM-dd'T'HH:mm:ssZ";
	public static void main(String[] args) throws Exception {
		 SimpleDateFormat sdf = new SimpleDateFormat(FORMAT);
	     String timestamp = sdf.format(new Date());

	     String constantValue="FacingIssuesOnIT";
	     String sessionId="ABCDEFGHIJKLMNOPQRSTUVWXYZ";

		 String tokenStr = constantValue+"$"+timestamp+"/06$"+sessionId;

		 System.out.println(tokenStr);

	    byte[] keyBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
	        0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };

	    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

	    SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");

	    // encryption url
	    cipher.init(Cipher.ENCRYPT_MODE, key);

	    byte[] cipherText = cipher.doFinal(tokenStr.getBytes());
        System.out.println("encrypted token size:" + cipherText.length);
        //Encode Character which are not allowed on URL
        String encodedTxt = Base64.encodeBase64URLSafeString(cipherText);

        System.out.println("EncodedEncryptedToken : " + encodedTxt);

	    //decryption url
        cipher.init(Cipher.DECRYPT_MODE, key);
        String decodeStr = URLDecoder.decode(
        		encodedTxt,
        StandardCharsets.UTF_8.toString());
        System.out.println("URL Decoder String :"+decodeStr);
        //Decode URl safe to base 64
        byte[] base64decodedTokenArr = Base64.decodeBase64(decodeStr.getBytes());

       byte[] decryptedPassword = cipher.doFinal(base64decodedTokenArr);
        //byte[] decryptedPassword = cipher.doFinal(decodeStr.getBytes());
       String  decodeTxt=new String(decryptedPassword);
       System.out.println("Token after decryption: " + decodeTxt);

	  }

}
 

More Sample Code

For more JAVA and JDBC codes follow below links