package com.zfire.jiasm.syncdata.gree;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.*;

public class CryptTool {
    public CryptTool() {
    }

    public static String byte2hex(byte[] b) {
        StringBuffer stringBuffer = new StringBuffer();
        String temp = null;

        for(int i = 0; i < b.length; ++i) {
            temp = Integer.toHexString(b[i] & 255);
            if (temp.length() == 1) {
                stringBuffer.append("0").append(temp);
            } else {
                stringBuffer.append(temp);
            }
        }

        return stringBuffer.toString();
    }

    public static byte[] decodeBase64(String key) {
        return Base64.decodeBase64(key);
    }

    public static SecretKeySpec initAESSecretKey(String secretKeySource) throws NoSuchAlgorithmException, DecoderException, UnsupportedEncodingException {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
        byte[] decodeHex = Hex.decodeHex(sha256(secretKeySource).toCharArray());
        secureRandom.setSeed(decodeHex);
        keyGen.init(128, secureRandom);
        SecretKey secretKey = keyGen.generateKey();
        byte[] secretKeyEncoded = secretKey.getEncoded();
        SecretKeySpec key = new SecretKeySpec(secretKeyEncoded, "AES");
        Security.addProvider(new BouncyCastleProvider());
        return key;
    }

    public static String decryptAES(String source, String secretKey) {
        try {
            byte[] sourceBytes = decodeBase64(source);
            SecretKeySpec secretKeySpec = initAESSecretKey(secretKey);
            byte[] decryptBytes = decrypt(source.getBytes(), secretKeySpec);
            return new String(decryptBytes, "utf8");
        } catch (Exception var5) {
            throw new RuntimeException("AES算法解密失败", var5);
        }
    }

    private static byte[] decrypt(byte[] source, SecretKeySpec secretKeySpec) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
        Cipher cipher = Cipher.getInstance(secretKeySpec.getAlgorithm());
        cipher.init(2, secretKeySpec);
        return cipher.doFinal(source);
    }

    public static String digest(byte[] inputBytes, String algorithm) throws NoSuchAlgorithmException {
        String outputStr = null;
        MessageDigest alg = MessageDigest.getInstance(algorithm);
        alg.update(inputBytes);
        byte[] digest = alg.digest();
        outputStr = byte2hex(digest);
        return outputStr.toUpperCase();
    }

    public static String sha1(String inStr) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        String outStr = digest(inStr.getBytes("UTF-8"), "SHA-1");
        return outStr;
    }

    public static String sha256(String inStr) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        String outStr = digest(inStr.getBytes("UTF-8"), "SHA-256");
        return outStr;
    }

    public static String md5(String inStr) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        String outStr = digest(inStr.getBytes("UTF-8"), "MD5");
        return outStr;
    }

    public static String encryptBASE64(byte[] key) throws Exception {
        return Base64.encodeBase64String(key);
    }

    public static String encryptAES(String source, String secretKey) {
        try {
            byte[] sourceBytes = source.getBytes("utf8");
            SecretKeySpec secretKeySpec = initAESSecretKey(secretKey);
            byte[] encryptBytes = encrypt(sourceBytes, secretKeySpec);
            return Base64.encodeBase64URLSafeString(encryptBytes);
        } catch (Exception var5) {
            throw new RuntimeException("AES算法加密失败", var5);
        }
    }

    private static byte[] encrypt(byte[] source, SecretKeySpec secretKeySpec) throws BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {
        Cipher cipher = Cipher.getInstance(secretKeySpec.getAlgorithm());
        cipher.init(1, secretKeySpec);
        return cipher.doFinal(source);
    }

    public static String encodeBase64String(byte[] source) {
        return Base64.encodeBase64String(source);
    }
}
