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

common.crypto.ECIES 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 javax.crypto.AEADBadTagException;
import java.security.*;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECPoint;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;

public class ECIES
{
  public static final int ECIES_GCM_IV_SIZE = 12;
  public static final int ECIES_GCM_TAG_SIZE = 12;

  public static byte[] encrypt(ECPublicKey pubKey, byte[] in)
  {
    try
    {
      EC.Curve curve = EC.getCurve(pubKey.getParams());
      if (curve==null)  throw new IllegalArgumentException("Curve not supported");

      KeyPairGenerator gen = SystemProvider.KeyPairGenerator.getInstance("EC");
      gen.initialize(curve.genSpec);
      KeyPair kp = gen.generateKeyPair();

      ECPublicKey ephemeralPub = (ECPublicKey)kp.getPublic();
      ECPrivateKey ephemeralPrv = (ECPrivateKey)kp.getPrivate();

      byte[] key = SHA256.hash(EC.ecdh(ephemeralPrv, pubKey));

      int curveSize = curve.size;
      int compressedPointSize = 1 + curveSize;
      byte[] out = new byte[1 + compressedPointSize + ECIES_GCM_IV_SIZE + in.length + ECIES_GCM_TAG_SIZE] ;
      out[0] = (byte)curve.dyCode;

      byte[] oct = curve.toCompressedOct(ephemeralPub.getW());
      System.arraycopy(oct, 0, out, 1, compressedPointSize);

      byte[] iv = CryptoRandom.generate(ECIES_GCM_IV_SIZE);
      System.arraycopy(iv, 0, out, 1+compressedPointSize, ECIES_GCM_IV_SIZE);

      byte[] enc = AES.GCM.encrypt(key, iv, ECIES_GCM_TAG_SIZE, in);
      System.arraycopy(enc, 0, out, 1+compressedPointSize+ECIES_GCM_IV_SIZE, enc.length);
      return out;
    }
    catch (Exception e) { throw new IllegalArgumentException(e); }
  }

  private static int getEncOffset(EC.Curve curve, byte[] in)
  {
    if (curve==null)  throw new IllegalArgumentException("Curve not supported");
    int curveSize = curve.size;
    int compressedPointSize = 1 + curveSize;
    int encOffset = 1 + compressedPointSize + ECIES_GCM_IV_SIZE;
    int encSize = in.length - encOffset;
    if (encSize < ECIES_GCM_TAG_SIZE) throw new IllegalArgumentException("Invalid input length");
    return encOffset;
  }

  public static ECPublicKey getPublicKey(byte[] in)
  {
    if (in.length < 1) throw new IllegalArgumentException("Invalid input length");
    EC.Curve curve = EC.getCurveByDyCode(in[0]);
    getEncOffset(curve, in);

    ECPoint point = curve.fromOct(in, 1, curve.size+1);
    ECPublicKeySpec keySpec = new ECPublicKeySpec(point, curve.spec);
    try { return (ECPublicKey) SystemProvider.KeyFactory.getInstance("EC").generatePublic(keySpec); }
    catch (InvalidKeySpecException e) { return null; }
  }

  public static byte[] decrypt(ECPrivateKey prvKey, byte[] in) throws AEADBadTagException
  {
    if (in.length < 1) throw new IllegalArgumentException("Invalid input length");
    EC.Curve curve = EC.getCurveByDyCode(in[0]);
    int encOffset = getEncOffset(curve, in);
    byte[] iv = Arrays.copyOfRange(in, encOffset-ECIES_GCM_IV_SIZE, encOffset);
    byte[] key = SHA256.hash(EC.ecdh(prvKey, getPublicKey(in)));
    return AES.GCM.decrypt(key, iv, ECIES_GCM_TAG_SIZE, Arrays.copyOfRange(in, encOffset, in.length));
  }

  public static byte[] decrypt(byte[] sharedSecret, byte[] in) throws AEADBadTagException
  {
    if (in.length < 1) throw new IllegalArgumentException("Invalid input length");
    EC.Curve curve = EC.getCurveByDyCode(in[0]);
    int encOffset = getEncOffset(curve, in);
    byte[] iv = Arrays.copyOfRange(in, encOffset-ECIES_GCM_IV_SIZE, encOffset);
    byte[] key = SHA256.hash(sharedSecret);
    return AES.GCM.decrypt(key, iv, ECIES_GCM_TAG_SIZE, Arrays.copyOfRange(in, encOffset, in.length));
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy