public static String decrypt(SecretKey secretKey, String encryptedText) throws Exception {
    Cipher cipher = Cipher.getInstance(CIPHER_MODE, PROVIDER_NAME);

    // separate and decode the initializationVector and aad from the encryptedBytes;
    String[] sections = encryptedText.split(PAYLOAD_SEPARATOR);
    byte[] iv = Base64.getDecoder().decode(sections[0]);
    byte[] aad = Base64.getDecoder().decode(sections[1]);
    byte[] encryptedTextBytes = Base64.getDecoder().decode(sections[2]);

    GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, iv);
    cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmParameterSpec);
    cipher.updateAAD(aad);

    byte[] byteDecryptedText = cipher.doFinal(encryptedTextBytes);
    return new String(byteDecryptedText);
  }
  public static String encrypt(SecretKey secretKey, String clearText) throws Exception {
    Cipher cipher = Cipher.getInstance(CIPHER_MODE, PROVIDER_NAME);

    final byte[] iv = new byte[12];
    new SecureRandom().nextBytes(iv);
    GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, iv);
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, gcmParameterSpec);

    final byte[] aad = new byte[12];
    new SecureRandom().nextBytes(aad);
    cipher.updateAAD(aad);

    byte[] encryptedBytes = cipher.doFinal(clearText.getBytes("UTF-8"));

    // The encrypted string will consist of the initializationVector + the authenticated encryption
    // data + the encryptedBytes;
    return new String(Base64.getEncoder().encode(iv), "UTF-8")
        + PAYLOAD_SEPARATOR
        + new String(Base64.getEncoder().encode(aad), "UTF-8")
        + PAYLOAD_SEPARATOR
        + new String(Base64.getEncoder().encode(encryptedBytes), "UTF-8");
  }
Exemple #3
0
  private void testGCMGeneric(byte[] K, byte[] N, byte[] A, byte[] P, byte[] C)
      throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
          IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException,
          NoSuchProviderException, IOException, InvalidParameterSpecException {
    Cipher eax = Cipher.getInstance("AES/GCM/NoPadding", "BC");
    SecretKeySpec key = new SecretKeySpec(K, "AES");

    // GCMParameterSpec mapped to AEADParameters and overrides default MAC
    // size
    GCMParameterSpec spec = new GCMParameterSpec(128, N);
    eax.init(Cipher.ENCRYPT_MODE, key, spec);

    eax.updateAAD(A);
    byte[] c = eax.doFinal(P);

    if (!areEqual(C, c)) {
      fail("JCE encrypt with additional data and GCMParameterSpec failed.");
    }

    eax = Cipher.getInstance("GCM", "BC");
    eax.init(Cipher.DECRYPT_MODE, key, spec);
    eax.updateAAD(A);
    byte[] p = eax.doFinal(C);

    if (!areEqual(P, p)) {
      fail("JCE decrypt with additional data and GCMParameterSpec failed.");
    }

    AlgorithmParameters algParams = eax.getParameters();

    byte[] encParams = algParams.getEncoded();

    GCMParameters gcmParameters = GCMParameters.getInstance(encParams);

    if (!Arrays.areEqual(spec.getIV(), gcmParameters.getNonce())
        || spec.getTLen() != gcmParameters.getIcvLen()) {
      fail("parameters mismatch");
    }

    GCMParameterSpec gcmSpec = algParams.getParameterSpec(GCMParameterSpec.class);

    if (!Arrays.areEqual(gcmSpec.getIV(), gcmParameters.getNonce())
        || gcmSpec.getTLen() != gcmParameters.getIcvLen() * 8) {
      fail("spec parameters mismatch");
    }

    if (!Arrays.areEqual(eax.getIV(), gcmParameters.getNonce())) {
      fail("iv mismatch");
    }
  }
Exemple #4
0
  private static byte[] gcmDecrypt(byte[] key, byte[] cipherText, byte[] aad, byte[] iv)
      throws AEADBadTagException {
    byte[] plainText = new byte[cipherText.length - BLOCK_SIZE];
    try {

      SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM);
      GCMParameterSpec gcmSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
      Cipher cipher = Cipher.getInstance(ALGORITHM + "/" + MODE + "/NoPadding");
      cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmSpec);

      if (aad != null && aad.length != 0) {
        cipher.updateAAD(aad);
      }

      // store internally until decryptFinal is called
      cipher.doFinal(cipherText, 0, cipherText.length, plainText, 0);

    } catch (AEADBadTagException e) {
      System.out.println(e.getMessage());
      throw e;
    } catch (Exception e) {
      System.out.println(e.getMessage());
    }
    return plainText;
  }
Exemple #5
0
  private static byte[] gcmEncrypt(byte[] key, byte[] plainText, byte[] aad, byte[] iv) {
    byte[] cipherText = new byte[plainText.length + 16];
    try {

      SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM);
      GCMParameterSpec gcmSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
      Cipher cipher = Cipher.getInstance(ALGORITHM + "/" + MODE + "/NoPadding");
      cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmSpec);

      if (aad != null && aad.length != 0) {
        cipher.updateAAD(aad);
      }

      // if has more than one blocks, test cipher.update
      if (plainText.length > 16) {
        cipher.update(plainText, 0, 16, cipherText, 0);
        cipher.doFinal(plainText, 16, plainText.length - 16, cipherText, 16);
      } else {
        // doFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)
        cipher.doFinal(plainText, 0, plainText.length, cipherText, 0);
      }

    } catch (Exception e) {
      System.out.println(e.getMessage());
    }
    return cipherText;
  }
Exemple #6
0
  private void checkCipherWithAD(byte[] K, byte[] N, byte[] A, byte[] P, byte[] C)
      throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
          IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException,
          NoSuchProviderException {
    Cipher eax = Cipher.getInstance("AES/EAX/NoPadding", "BC");
    SecretKeySpec key = new SecretKeySpec(K, "AES");
    IvParameterSpec iv = new IvParameterSpec(N);
    eax.init(Cipher.ENCRYPT_MODE, key, iv);

    eax.updateAAD(A);
    byte[] c = eax.doFinal(P);

    if (!areEqual(C, c)) {
      fail("JCE encrypt with additional data failed.");
    }

    eax.init(Cipher.DECRYPT_MODE, key, iv);
    eax.updateAAD(A);
    byte[] p = eax.doFinal(C);

    if (!areEqual(P, p)) {
      fail("JCE decrypt with additional data failed.");
    }
  }
Exemple #7
0
  private void testGCMParameterSpecWithRepeatKey(byte[] K, byte[] N, byte[] A, byte[] P, byte[] C)
      throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
          IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException,
          NoSuchProviderException, IOException {
    Cipher eax = Cipher.getInstance("AES/EAX/NoPadding", "BC");
    SecretKeySpec key = new SecretKeySpec(K, "AES");
    GCMParameterSpec spec = new GCMParameterSpec(128, N);
    eax.init(Cipher.ENCRYPT_MODE, key, spec);

    eax.updateAAD(A);
    byte[] c = eax.doFinal(P);

    if (!areEqual(C, c)) {
      fail("JCE encrypt with additional data and RepeatedSecretKeySpec failed.");
    }

    // Check GCMParameterSpec handling knows about RepeatedSecretKeySpec
    eax.init(Cipher.DECRYPT_MODE, new RepeatedSecretKeySpec("AES"), spec);
    eax.updateAAD(A);
    byte[] p = eax.doFinal(C);

    if (!areEqual(P, p)) {
      fail("JCE decrypt with additional data and RepeatedSecretKeySpec failed.");
    }

    AlgorithmParameters algParams = eax.getParameters();

    byte[] encParams = algParams.getEncoded();

    GCMParameters gcmParameters = GCMParameters.getInstance(encParams);

    if (!Arrays.areEqual(spec.getIV(), gcmParameters.getNonce())
        || spec.getTLen() != gcmParameters.getIcvLen()) {
      fail("parameters mismatch");
    }
  }