import com.google.common.base.Charsets;
import org.apache.commons.lang3.ArrayUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Security;
// For Java and JVM-based languages, you might need to install unrestricted policy file for JVM,
// which is provided by Sun. Please refer BouncyCastle FAQ if you get
// java.lang.SecurityException: Unsupported keysize or algorithm parameters or
// java.security.InvalidKeyException: Illegal key size.
// If you cannot install unrestricted policy file for JVM because of some reason, you can try with reflection: See here.
public class Decryption
{
public static void main(String[] args) throws Exception
{
Security.addProvider(new BouncyCastleProvider());
// Data from configuration
String keyFromConfiguration = "000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f";
// Data from server
String ivFromHttpHeader = "000000000000000000000000";
String authTagFromHttpHeader = "CE573FB7A41AB78E743180DC83FF09BD";
String httpBody = "0A3471C72D9BE49A8520F79C66BBD9A12FF9";
// Convert data to process
byte[] key = DatatypeConverter.parseHexBinary(keyFromConfiguration);
byte[] iv = DatatypeConverter.parseHexBinary(ivFromHttpHeader);
byte[] authTag = DatatypeConverter.parseHexBinary(authTagFromHttpHeader);
byte[] encryptedText = DatatypeConverter.parseHexBinary(httpBody);
// Unlike other programming language, We have to append auth tag at the end of encrypted text in Java
byte[] cipherText = ArrayUtils.addAll(encryptedText, authTag);
// Prepare decryption
SecretKeySpec keySpec = new SecretKeySpec(key, 0, 32, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));
// Decrypt
byte[] bytes = cipher.doFinal(cipherText);
System.out.println(new String(bytes, Charsets.UTF_8));
}
} |