Main.java Source code

Java tutorial

Introduction

Here is the source code for Main.java

Source

//package com.java2s;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import java.nio.ByteBuffer;
import java.security.*;

import java.util.Arrays;

public class Main {
    static final int AES_BLOCK_SIZE = 16;

    public static byte[] messageEncrypt(byte[] authKey, byte[] msgKey, byte[] data, boolean isOut) {
        byte[] key = getAESkey(authKey, msgKey, isOut);
        byte[] iv = getAESiv(authKey, msgKey, isOut);

        return aesIGEencrypt(iv, key, data);
    }

    public static byte[] getAESkey(byte[] authKey, byte[] msgKey, boolean isOut) {
        int x = 0;
        if (!isOut)
            x = 8;

        ByteBuffer tempA = ByteBuffer.allocate(msgKey.length + 32);
        tempA.put(msgKey);
        tempA.put(authKey, x, 32);
        byte[] a = getSHA1hash(tempA.array());

        ByteBuffer tempB = ByteBuffer.allocate(msgKey.length + 32);
        tempB.put(authKey, 32 + x, 16);
        tempB.put(msgKey);
        tempB.put(authKey, 48 + x, 16);
        byte[] b = getSHA1hash(tempB.array());

        ByteBuffer tempC = ByteBuffer.allocate(msgKey.length + 32);
        tempC.put(authKey, 64 + x, 32);
        tempC.put(msgKey);
        byte[] c = getSHA1hash(tempC.array());

        ByteBuffer key = ByteBuffer.allocate(8 + 12 + 12);
        key.put(a, 0, 8);
        key.put(b, 8, 12);
        key.put(c, 4, 12);

        return key.array();
    }

    public static byte[] getAESiv(byte[] authKey, byte[] msgKey, boolean isOut) {
        int x = 0;
        if (!isOut)
            x = 8;

        ByteBuffer tempA = ByteBuffer.allocate(msgKey.length + 32);
        tempA.put(msgKey);
        tempA.put(authKey, x, 32);
        byte[] a = getSHA1hash(tempA.array());

        ByteBuffer tempB = ByteBuffer.allocate(msgKey.length + 32);
        tempB.put(authKey, 32 + x, 16);
        tempB.put(msgKey);
        tempB.put(authKey, 48 + x, 16);
        byte[] b = getSHA1hash(tempB.array());

        ByteBuffer tempC = ByteBuffer.allocate(msgKey.length + 32);
        tempC.put(authKey, 64 + x, 32);
        tempC.put(msgKey);
        byte[] c = getSHA1hash(tempC.array());

        ByteBuffer tempD = ByteBuffer.allocate(msgKey.length + 32);
        tempD.put(msgKey);
        tempD.put(authKey, 96 + x, 32);
        byte[] d = getSHA1hash(tempD.array());

        ByteBuffer iv = ByteBuffer.allocate(12 + 8 + 4 + 8);
        iv.put(a, 8, 12);
        iv.put(b, 0, 8);
        iv.put(c, 16, 4);
        iv.put(d, 0, 8);

        return iv.array();
    }

    public static byte[] aesIGEencrypt(byte[] tmpAESiv, byte[] tmpAesKey, byte[] data) {
        try {

            ByteBuffer out = ByteBuffer.allocate(data.length);

            byte[] ivp = Arrays.copyOfRange(tmpAESiv, 0, tmpAESiv.length / 2);
            byte[] iv2p = Arrays.copyOfRange(tmpAESiv, tmpAESiv.length / 2, tmpAESiv.length);

            int len = data.length / AES_BLOCK_SIZE;

            byte[] xorInput = null;
            byte[] xorOutput = null;

            SecretKeySpec keySpec = null;
            keySpec = new SecretKeySpec(tmpAesKey, "AES");
            Cipher cipher = null;
            cipher = Cipher.getInstance("AES/ECB/NoPadding");
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);

            byte[] input = null;
            byte[] output = null;

            for (int i = 0; i < len; i++) {

                input = Arrays.copyOfRange(data, i * AES_BLOCK_SIZE, (i + 1) * AES_BLOCK_SIZE);
                xorInput = xor(input, ivp);
                output = cipher.doFinal(xorInput);
                xorOutput = xor(output, iv2p);
                out.put(xorOutput);

                ivp = xorOutput;
                iv2p = input;
            }
            return out.array();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] getSHA1hash(byte[] dataByte) {
        MessageDigest md = null;
        byte[] sha1hash = new byte[20];
        try {
            md = MessageDigest.getInstance("SHA-1");
            md.update(dataByte, 0, dataByte.length);
            sha1hash = md.digest();
            return sha1hash;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
        }
        return null;
    }

    public static byte[] xor(byte[] a, byte[] b) {
        if (a.length == b.length) {
            byte[] res = new byte[a.length];
            for (int i = 0; i < a.length; i++) {
                res[i] = (byte) (a[i] ^ b[i]);
            }
            return res;
        } else
            return null;
    }
}