All Downloads are FREE. Search and download functionalities are using the official Maven repository.

common.crypto.AES Maven / Gradle / Ivy

Go to download

This is a collection of JAVA libraries that implement Unbound cryptographic classes for JAVA provider, PKCS11 wrapper, cryptoki, and advapi

There is a newer version: 42761
Show newest version
package com.unbound.common.crypto;

import com.unbound.common.Converter;

import javax.crypto.*;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Arrays;

public final class AES
{
  private Cipher cipher;
  byte[] key;

  public AES(byte[] key)
  {
    this.key = key;
    cipher = SystemProvider.Cipher.getInstance("AES/ECB/NoPadding");
  }

  private void checkInit(int mode)
  {
    try
    {
      if (key!=null)
      {
        cipher.init(mode, new SecretKeySpec(key, "AES"));
        key = null;
      }
    }
    catch (Exception e) { throw new IllegalArgumentException(e); }
  }

  public byte[] encrypt(byte[] in)
  {
    checkInit(Cipher.ENCRYPT_MODE);
    return cipher.update(in);
  }

  public AES encrypt(byte[] in, int inOffset, int inLength, byte[] out, int outOffset)
  {
    try
    {
      checkInit(Cipher.ENCRYPT_MODE);
      cipher.update(in, inOffset, inLength, out, outOffset);
      return this;
    }
    catch (Exception e) { throw new IllegalArgumentException(e); }
  }

  public byte[] decrypt(byte[] in)
  {
    checkInit(Cipher.DECRYPT_MODE);
    return cipher.update(in);
  }

  public AES decrypt(byte[] in, int inOffset, int inLength, byte[] out, int outOffset)
  {
    try
    {
      checkInit(Cipher.DECRYPT_MODE);
      cipher.update(in, inOffset, inLength, out, outOffset);
      return this;
    }
    catch (Exception e) { throw new IllegalArgumentException(e); }
  }

  static byte[] encrypt(byte[] key, byte[] in)
  {
    return new AES(key).encrypt(in);
  }

  static byte[] decrypt(byte[] key, byte[] in)
  {
    return new AES(key).decrypt(in);
  }

  public static final class GCM
  {

    public static byte[] encrypt(byte[] key, byte[] iv, int tagLen, byte[] in)
    {
      return encrypt(key, iv, null, tagLen, in);
    }

    public static byte[] encrypt(byte[] key, byte[] iv, byte[] aad, int tagLen, byte[] in)
    {
      try
      {
        byte[] out = new byte[in.length + tagLen];
        GCMParameterSpec params = new GCMParameterSpec(tagLen * 8, iv);
        Cipher cipher = SystemProvider.Cipher.getInstance("AES/GCM/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), params);
        if (aad!=null && aad.length>0) cipher.updateAAD(aad);
        int tempSize = cipher.update(in, 0, in.length, out, 0);
        cipher.doFinal(out, tempSize);
        return out;
      }
      catch (Exception e) { throw new IllegalArgumentException(e); }
    }


    public static byte[] decrypt(byte[] key, byte[] iv, int tagLen, byte[] in) throws AEADBadTagException
    {
      return decrypt(key, iv, null, tagLen, in);
    }

    public static byte[] decrypt(byte[] key, byte[] iv, byte[] aad, int tagLen, byte[] in) throws AEADBadTagException
    {
      try
      {
        byte[] out = new byte[in.length - tagLen];
        GCMParameterSpec params = new GCMParameterSpec(tagLen * 8, iv);
        Cipher cipher = SystemProvider.Cipher.getInstance("AES/GCM/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), params);
        if (aad!=null && aad.length>0) cipher.updateAAD(aad);
        int tempSize = cipher.update(in, 0, in.length, out, 0);
        cipher.doFinal(out, tempSize);
        return out;
      }
      catch (AEADBadTagException e) { throw e; }
      catch (Exception e) { throw new IllegalArgumentException(e); }
    }
  }

  public static final class XTS
  {
    private static void gfMulX128LE(byte[] ps)
    {
      long whiteningLo = Converter.getLE8(ps, 0);
      long whiteningHi = Converter.getLE8(ps, 8);

      int finalCarry = (0 == (whiteningHi & 0x8000000000000000L)) ? 0 : 135;

      whiteningHi <<= 1;
      whiteningHi |= whiteningLo >>> 63;
      whiteningLo <<= 1;
      whiteningLo ^= finalCarry;

      Converter.setLE8(ps, 0, whiteningLo);
      Converter.setLE8(ps, 8, whiteningHi);
    }

    private static void xor(byte[] dst, int dstOffset, byte[] src1, int srcOffset1, byte[] src2, int srcOffset2)
    {
      for (int i=0; i<16; i++) dst[dstOffset+i] = (byte)(src1[srcOffset1+i] ^ src2[srcOffset2+i]);
    }

    static byte[] encrypt(byte[] key, byte[] plain)
    {
      byte[] encrypted = new byte[plain.length];
      try
      {
        byte[] k1 = Arrays.copyOfRange(key, 0, 16);
        byte[] k2 = Arrays.copyOfRange(key, 16, 32);
        byte[] iv = new byte[16]; // zeroes
        byte[] ps = new AES(k2).encrypt(iv);
        Cipher cipher = SystemProvider.Cipher.getInstance("AES/ECB/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(k1, "AES"));

        byte[] temp = new byte[16];
        int n = plain.length/16;
        int offset = 0;
        for (int i = 0; i0 && i==n-1)
          {
            System.arraycopy(ps, 0, psSave, 0, 16);
            gfMulX128LE(ps);
          }

          xor(temp, 0, ps, 0, encrypted, offset);
          cipher.update(temp, 0, 16, temp);
          xor(plain, offset, temp, 0, ps, 0);

          gfMulX128LE(ps);
        }

        if (tail>0)
        {
          for (int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy