package com.device.comm.mylibrary.NativeDevice;

import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

public class InvsDes3
{
  public static final String KEY_ALGORITHM = "desede";
  public static final String CIPHER_ALGORITHM = "desede/CBC/NoPadding";
  
  public InvsDes3() {}
  
  public static byte[] Fill8Char(byte[] data)
  {
    byte[] dataa = null;
    int iLen = data.length % 8;
    if (iLen != 0)
    {
      dataa = new byte[(data.length / 8 + 1) * 8];
      System.arraycopy(data, 0, dataa, 0, data.length);
      iLen = 8 - iLen;
      for (int i = 0; i < iLen; i++) {
        dataa[(data.length + i)] = 0;
      }
    }
    else
    {
      dataa = new byte[data.length];
      System.arraycopy(data, 0, dataa, 0, data.length);
    }
    return dataa;
  }
  
  public static byte[] Fill24Key(byte[] key)
  {
    byte[] keya = new byte[24];
    System.arraycopy(key, 0, keya, 0, key.length);
    if (key.length == 16) {
      System.arraycopy(key, 0, keya, 16, 8);
    }
    return keya;
  }
  
  public static byte[] des3EncodeECB(byte[] key, byte[] data)
    throws Exception
  {
    data = Fill8Char(data);
    key = Fill24Key(key);
    
    Key deskey = null;
    DESedeKeySpec spec = new DESedeKeySpec(key);
    SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
    deskey = keyfactory.generateSecret(spec);
    
    Cipher cipher = Cipher.getInstance("desede/CBC/NoPadding");
    
    cipher.init(1, deskey);
    byte[] bOut = cipher.doFinal(data);
    
    return bOut;
  }
  
  public static byte[] des3DecodeECB(byte[] key, byte[] data)
    throws Exception
  {
    data = Fill8Char(data);
    key = Fill24Key(key);
    
    Key deskey = null;
    DESedeKeySpec spec = new DESedeKeySpec(key);
    SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
    deskey = keyfactory.generateSecret(spec);
    
    Cipher cipher = Cipher.getInstance("desede/CBC/NoPadding");
    
    cipher.init(2, deskey);
    
    byte[] bOut = cipher.doFinal(data);
    
    return bOut;
  }
  
  public static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data)
    throws Exception
  {
    data = Fill8Char(data);
    key = Fill24Key(key);
    
    Key deskey = null;
    DESedeKeySpec spec = new DESedeKeySpec(key);
    SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
    deskey = keyfactory.generateSecret(spec);
    
    Cipher cipher = Cipher.getInstance("desede/CBC/NoPadding");
    if (keyiv == null)
    {
      keyiv = new byte[8];
      for (int i = 0; i < 8; i++) {
        keyiv[i] = ((byte)i);
      }
    }
    IvParameterSpec ips = new IvParameterSpec(keyiv);
    cipher.init(1, deskey, ips);
    byte[] bOut = cipher.doFinal(data);
    
    return bOut;
  }
  
  public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data)
    throws Exception
  {
    data = Fill8Char(data);
    key = Fill24Key(key);
    
    Key deskey = null;
    DESedeKeySpec spec = new DESedeKeySpec(key);
    SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
    deskey = keyfactory.generateSecret(spec);
    
    Cipher cipher = Cipher.getInstance("desede/CBC/NoPadding");
    if (keyiv == null)
    {
      keyiv = new byte[8];
      for (int i = 0; i < 8; i++) {
        keyiv[i] = ((byte)i);
      }
    }
    IvParameterSpec ips = new IvParameterSpec(keyiv);
    
    cipher.init(2, deskey, ips);
    
    byte[] bOut = cipher.doFinal(data);
    
    return bOut;
  }
}

