0

I try to use java7 to achieve AES-256-GCM decoding I encountered a mac check failure response in GCM Please help me out, thank you all.

import java.security.Security;

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

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

  public static void main(String[] args) throws Exception {
    String iv = "35d117c42d1c1835420b6b9942dd4f1b"; // utf-8
    String key = "3a7bd3e2360a3d29eea436fcfb7e44c7"; // utf-8
    String hexCipherString = "07a604fc0c143a6e"; // hex
    String hexAuthTagString = "984e81176ff260717beb184db3d73753"; //hex

    byte[] decodedCipherHexBtye = Hex.decodeHex(hexCipherString.toCharArray());
    byte[] base64Cipher = Base64.decodeBase64(decodedCipherHexBtye);
    byte[] decodedAuthTagHex = Hex.decodeHex(hexAuthTagString.toCharArray());
    byte[] base64AuthTag = Base64.decodeBase64(decodedAuthTagHex);

    SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
    byte[] gcmIv = iv.getBytes("UTF-8");

    Security.addProvider(new BouncyCastleProvider());
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
    GCMParameterSpec params = new GCMParameterSpec(base64AuthTag.length * Byte.SIZE, gcmIv);
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, params);
    cipher.updateAAD(base64AuthTag);
    byte[] result = cipher.doFinal(base64Cipher);
    System.out.println(Base64.encodeBase64(result));
  }

I am looking forward to the expected result of Base64Encode: dGVzdA==

庭偉林
  • 56
  • 3

3 Answers3

1

How to address the Security warning comment to implement safe code.

The core issue in the warning is the need for a randomly generated IV (a set of truly random bytes) for each encryption

when you make a Cypher here is a concrete example using Java 8 Oracle SE

       val cipher = Cipher.getInstance("some scheme", "some provider");

then when we use the the Cypher safely we need a true random initialization vector IV to correctly resolve the issue this warning is directing us too,

turns out at least in Oracle Java 8 this is easy,

with the above cypher

    cipher.getIV()

the instance method for the cipher object is safe see

generally use with IvParameterSpec

    ivParams = IvParameterSpec( cipher.getIV())
    cipher.init(Cipher.ENCRYPT_MODE, key, ivParams);
Nigel Savage
  • 991
  • 13
  • 26
0

I found a solution and modified the code as follows:

  public static void main(String[] args) throws Exception {
    String iv = "35d117c42d1c1835420b6b9942dd4f1b"; // utf-8
    String key = "3a7bd3e2360a3d29eea436fcfb7e44c7"; // utf-8
    String hexCipherString = "07a604fc0c143a6e"; // hex
    String hexAuthTagString = "984e81176ff260717beb184db3d73753"; //hex

    byte[] decodedCipherHexBtye = Hex.decodeHex(hexCipherString.toCharArray());
    byte[] decodedAuthTagHex = Hex.decodeHex(hexAuthTagString.toCharArray());

    SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
    byte[] gcmIv = iv.getBytes("UTF-8");

    Security.addProvider(new BouncyCastleProvider());
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
    GCMParameterSpec params = new GCMParameterSpec(decodedAuthTagHex.length * Byte.SIZE, gcmIv);
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, params);
    cipher.update(decodedCipherHexBtye);
    byte[] result = cipher.doFinal(decodedAuthTagHex);
    
    System.out.println(new String(result));
  }

Refer to this article Tag mismatch error in AES-256-GCM Decryption using Java

庭偉林
  • 56
  • 3
  • 1
    **Security warning**: the usage of **static/fixed** initialization vector makes the encryption in AES GCM mode **unsecure**, do not use this in production. Generate a randomly generated IV for each encryption and ship it along with the ciphertext. – Michael Fehr Jul 15 '21 at 06:26
0

This is the easiest way to encryption and decryption using AES-256.

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
     String decryptedData = AESUtils.decrypt("Your Encrypted Data");
     System.out.println(decryptedData);
}

public class AESUtils {
private static final String ENCRYPTION_KEY = "RwcmlVpg";
private static final String ENCRYPTION_IV = "5183666c72eec9e4";

@RequiresApi(api = Build.VERSION_CODES.O)
public static String encrypt(String src) {
    try {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, makeKey(), makeIv());
        byte[] origignal= Base64.encode(cipher.doFinal(src.getBytes()),Base64.DEFAULT);
        return new String(origignal);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

@RequiresApi(api = Build.VERSION_CODES.O)
public static String decrypt(String src) {
    String decrypted = "";
    try {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, makeKey(), makeIv());
        byte[] decode = Base64.decode(src, Base64.NO_WRAP);
        decrypted= new String(cipher.doFinal(decode), "UTF-8");
    } catch (Exception e) {
        Log.v("AES Exception", String.valueOf(e));

        throw new RuntimeException(e);
    }
    return decrypted;
}

static AlgorithmParameterSpec makeIv() {
    try {
        return new IvParameterSpec(ENCRYPTION_IV.getBytes("UTF-8"));
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return null;
}

static Key makeKey() {
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] key = md.digest(ENCRYPTION_KEY.getBytes("UTF-8"));
        return new SecretKeySpec(key, "AES");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    return null;
}
}
  • 3
    **Security warning** The use of a **static IV** make your complete encryption **UNSECURE** - please do not use this code. Use a randomly generated IV and prepend it to the ciphertext, thanks. – Michael Fehr Aug 28 '21 at 12:30
  • Please help me to generate random IV. – Hardik kotadiya Oct 11 '22 at 05:23
  • 1
    Please find a method for Generation of a random IV here: https://github.com/java-crypto/cross_platform_crypto/blob/main/AesCbc256StringEncryption/AesCbc256StringEncryption.java#L52 – Michael Fehr Oct 11 '22 at 22:22