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

public class AES {
  public static final String AES_SECRETKEYSPEC = "AES";
  
  public static final int AES_KEY_SIZE = 256;
  
  public static final int GCM_IV_LENGTH = 12;
  
  public static final int GCM_TAG_LENGTH = 16;
  
  private static final String AES_TRANSFORMATION = "AES/GCM/NoPadding";
  
  private static final String encrypt = "encrypt";
  
  private static final String decrypt = "decrypt";
  
  public static void main(String[] paramArrayOfString) {
    if (paramArrayOfString.length != 3) {
      System.out.println("Usage : java encrypt/decrypt text key/Token");
      System.exit(-1);
    } 
    String str1 = paramArrayOfString[0];
    String str2 = paramArrayOfString[1];
    String str3 = paramArrayOfString[2];
    String str4 = null;
    if (str1.equals("encrypt")) {
      str4 = encrypt(str2, str3);
    } else if (str1.equals("decrypt")) {
      str4 = decrypt(str2, str3);
    } else {
      System.out.println("Usage : java encrypt/decrypt text key/Token");
      System.exit(-1);
    } 
    System.out.println(str4);
  }
  
  private static String encrypt(String paramString1, String paramString2) {
    try {
      Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
      SecretKeySpec secretKeySpec = new SecretKeySpec(HexfromString(paramString2), "AES");
      GCMParameterSpec gCMParameterSpec = new GCMParameterSpec(128, HexfromString(paramString2.substring(0, 12)));
      cipher.init(1, secretKeySpec, gCMParameterSpec);
      byte[] arrayOfByte = cipher.doFinal(paramString1.getBytes());
      return HextoString(arrayOfByte);
    } catch (Exception exception) {
      System.out.println("Exception: " + exception.getMessage());
      return null;
    } 
  }
  
  private static String decrypt(String paramString1, String paramString2) {
    try {
      Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
      byte[] arrayOfByte1 = HexfromString(paramString2);
      SecretKeySpec secretKeySpec = new SecretKeySpec(arrayOfByte1, "AES");
      byte[] arrayOfByte2 = HexfromString(paramString2.substring(0, 12));
      GCMParameterSpec gCMParameterSpec = new GCMParameterSpec(128, arrayOfByte2);
      cipher.init(2, secretKeySpec, gCMParameterSpec);
      byte[] arrayOfByte3 = HexfromString(paramString1);
      byte[] arrayOfByte4 = cipher.doFinal(arrayOfByte3);
      return new String(arrayOfByte4);
    } catch (Exception exception) {
      System.out.println("Exception: " + exception.getMessage());
      return null;
    } 
  }
  
  private static byte[] HexfromString(String paramString) {
    int i = paramString.length();
    byte[] arrayOfByte = new byte[(i + 1) / 2];
    byte b1 = 0;
    byte b2 = 0;
    if (i % 2 == 1)
      arrayOfByte[b2++] = (byte)HexfromDigit(paramString.charAt(b1++)); 
    while (b1 < i)
      arrayOfByte[b2++] = (byte)(HexfromDigit(paramString.charAt(b1++)) << 4 | HexfromDigit(paramString.charAt(b1++))); 
    return arrayOfByte;
  }
  
  private static int HexfromDigit(char paramChar) {
    if (paramChar >= '0' && paramChar <= '9')
      return paramChar - 48; 
    if (paramChar >= 'A' && paramChar <= 'F')
      return paramChar - 65 + 10; 
    if (paramChar >= 'a' && paramChar <= 'f')
      return paramChar - 97 + 10; 
    throw new IllegalArgumentException("invalid hex digit: " + paramChar);
  }
  
  private static String HextoString(byte[] paramArrayOfbyte) {
    return HextoString(paramArrayOfbyte, 0, paramArrayOfbyte.length);
  }
  
  private static String HextoString(byte[] paramArrayOfbyte, int paramInt1, int paramInt2) {
    char[] arrayOfChar = new char[paramInt2 * 2];
    byte b = 0;
    for (int i = paramInt1; i < paramInt1 + paramInt2; i++) {
      byte b1 = paramArrayOfbyte[i];
      arrayOfChar[b++] = hexDigits[b1 >>> 4 & 0xF];
      arrayOfChar[b++] = hexDigits[b1 & 0xF];
    } 
    return new String(arrayOfChar);
  }
  
  private static final char[] hexDigits = new char[] { 
      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
      'A', 'B', 'C', 'D', 'E', 'F' };
}

