api介面資料安全格式轉換-DES,AES,SM2

oktokeep發表於2024-08-11

api介面資料安全格式轉換-DES,AES,SM2

1.資料格式
{
"orderNo":"",
//其他的業務資料
}

返回
{
"sign":"",
"params":"",
"timestamp":""
}

實現介面的加密傳輸,資料安全規範。

返回DEMO
sign=8E4D93D831652C94473994DBB0846F11,
params=043be4139761bc5ad25e1d52eb78ba63e06d514a62c20abf4683f3eeabaa04dcdab574a25d92b271ba698550045d7bbc7909d0f50121963cc6b9d1cd0cdcd693d4537f0bd7d1727f7e7970eb6039735e541fae3bb62359d5f7374f86dda121d1e24a2b36d4c72fb9e5be91479ad06e6a91f44577cfc9,
timestamp=1722240158754

本次需要使用的jar包:下載地址
hutool-all-5.3.0.jar
bcprov-jdk15on-1.62.jar


注意點:jar包衝突。。
BJCA-JCE2.jar (連結:SM4Utils加解密demo https://www.cnblogs.com/oktokeep/p/17304702.html)
bcprov-jdk15on-1.62.jar

org.bouncycastle.jce.provider;
org.bouncycastle.jce.provider;

BCECPublicKey.java
BCECPublicKey

org.bouncycastle.jcajce.provider.asymmetric.ec;
org.bouncycastle.jcajce.provider.asymmetric.ec;

如果專案中同時使用SM4和SM2的方式,會存在jar衝突,發現兩個jar包中的類存在同路徑同名稱的情況,導致程式碼報錯。
只能選擇其中之一,避免jar衝突。


示例程式碼
2.AESUtil.java DESWX.java ParamCipher.java main方法演示: AES,DES

package tool;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @version V1.0
 * @desc AES 加密工具類
 */
public class AESUtil {
    private static org.slf4j.Logger log = LoggerFactory.getLogger(AESUtil.class);

    public enum Algorithm {
        PKCS5("AES/ECB/PKCS5Padding"), PKCS7("AES/ECB/PKCS7Padding"), CBCPKCS7("AES/CBC/PKCS7Padding");
        private String algorithm;

        Algorithm(String algorithm) {
            this.algorithm = algorithm;
        }

        public String getAlgorithm() {
            return algorithm;
        }

        public void setAlgorithm(String algorithm) {
            this.algorithm = algorithm;
        }
    }

    private static boolean initialized = false;
    private static final String KEY_ALGORITHM = "AES";
    private static byte[] iv = {0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38};

    public static void initialize() {
        if (initialized) {
            return;
        }
        Security.addProvider(new BouncyCastleProvider());
        initialized = true;
    }

    /**
     * 生成加密秘鑰
     *
     * @return
     */
    private static Key getSecretKey(byte[] keyBytes) {
        //返回生成指定演算法金鑰生成器的 KeyGenerator 物件
        KeyGenerator kg = null;
        try {
            kg = KeyGenerator.getInstance(KEY_ALGORITHM);
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            random.setSeed(keyBytes);
            //AES 要求金鑰長度為 128
            kg.init(128, random);
            //生成一個金鑰
            SecretKey secretKey = kg.generateKey();
            return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 轉換為AES專用金鑰
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public static Key getKey(byte[] keyBytes) {
        // 如果金鑰不足16位,那麼就補足.  這個if 中的內容很重要
        int base = 16;
        if (keyBytes.length % base != 0) {
            int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
            keyBytes = temp;
        }
        // 轉化成JAVA的金鑰格式
        return new SecretKeySpec(keyBytes, KEY_ALGORITHM);
    }

    /**
     * 加密方法
     *
     * @param content  要加密的字串
     * @param keyBytes 加密金鑰
     * @return
     */
//    @SneakyThrows
    public static byte[] encrypt(byte[] content, byte[] keyBytes, Algorithm algorithm) throws Exception{
        byte[] encryptedText;
        Key key;
        Cipher cipher;
        initialize();
        if (algorithm.equals(Algorithm.PKCS5)) {
            key = getSecretKey(keyBytes);
            cipher = Cipher.getInstance(algorithm.getAlgorithm());// 建立密碼器

        } else {
            key = getKey(keyBytes);
            cipher = Cipher.getInstance(algorithm.getAlgorithm(), "BC");
        }
        if (algorithm.equals(Algorithm.PKCS5) || algorithm.equals(Algorithm.PKCS7)) {
            cipher.init(Cipher.ENCRYPT_MODE, key);
        } else {
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
        }
        encryptedText = cipher.doFinal(content);
        return encryptedText;
    }

    /**
     * 解密方法
     *
     * @param encryptedData 要解密的字串
     * @param keyBytes      解密金鑰
     * @return
     */
//    @SneakyThrows
    public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes, byte[] ivBytes, Algorithm algorithm) throws Exception{
        byte[] encryptedText;
        Key key;
        Cipher cipher;
        initialize();
        if (algorithm.equals(Algorithm.PKCS5)) {
            key = getSecretKey(keyBytes);
            cipher = Cipher.getInstance(algorithm.getAlgorithm());// 建立密碼器

        } else {
            key = getKey(keyBytes);
            cipher = Cipher.getInstance(algorithm.getAlgorithm(), "BC");
        }
        if (algorithm.equals(Algorithm.PKCS5) || algorithm.equals(Algorithm.PKCS7)) {
            cipher.init(Cipher.DECRYPT_MODE, key);
        } else {
            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivBytes));
        }
        encryptedText = cipher.doFinal(encryptedData);
        return encryptedText;
    }

    public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes, Algorithm algorithm) throws Exception{
        return decrypt(encryptedData, keyBytes, iv, algorithm);
    }

    /**
     * @param str 要被加密的字串
     * @param key 加/解密要用的長度為32的位元組陣列(256位)金鑰
     * @return byte[]  加密後的位元組陣列
     */
    public static String encrypt(String str, String key, Algorithm algorithm) {
        try {
            byte[] bytes = encrypt(str.getBytes(StandardCharsets.UTF_8), key.getBytes(StandardCharsets.UTF_8), algorithm);
            return Base64.encodeBase64String(bytes);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("加密異常22:"+e.getLocalizedMessage());
        }
        return null;
    }

    public static String encryptByPKCS5(String str, String key) {
        return encrypt(str, key, Algorithm.PKCS5);
    }

    public static String encryptByPKCS7(String str, String key) {
        return encrypt(str, key, Algorithm.PKCS7);
    }

    public static String encryptByCBCPKCS7(String str, String key) {
        return encrypt(str, key, Algorithm.CBCPKCS7);
    }

    /**
     * @param str 要被解密的位元組陣列
     * @param key 加/解密要用的長度為32的位元組陣列(256位)金鑰
     * @return String  解密後的字串
     */

    public static String decrypt(String str, String key, Algorithm algorithm) {
        try {
            byte[] bytes = Base64.decodeBase64(str);
            bytes = decrypt(bytes, key.getBytes(StandardCharsets.UTF_8), algorithm);
            return new String(bytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
        }
        return null;
    }

    public static String decryptByPKCS5(String str, String key) {
        return decrypt(str, key, Algorithm.PKCS5);
    }

    public static String decryptByPKCS7(String str, String key) {
        return decrypt(str, key, Algorithm.PKCS7);
    }

    public static String decryptByCBCPKCS7(String str, String key) {
        return decrypt(str, key, Algorithm.CBCPKCS7);
    }

}
package tool;


import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;

//DES加解密方法
public class DESWX {
    private final static String DES = "DES";
    private final static String ENCODE = "UTF-8";
    private final static String DEFAULTKEY = "you default key";


    /**
     * 使用 預設key 加密
     * @return String
     */
    public static String encrypt(String data) throws Exception {
        byte[] bt = encrypt(data.getBytes(ENCODE), DEFAULTKEY.getBytes(ENCODE));
        String strs = new String(Base64.encodeBase64(bt));
        return strs;
    }

    /**
     * 使用 預設key 解密
     *
     * @return String
     */
    public static String decrypt(String data) throws IOException, Exception {
        if (data == null) {
            return null;
        }
        byte[] buf = Base64.decodeBase64(data);
        byte[] bt = decrypt(buf, DEFAULTKEY.getBytes(ENCODE));
        return new String(bt, ENCODE);
    }

    /**
     * Description 根據鍵值進行加密
     *
     * @param data
     * @param key  加密鍵byte陣列
     * @return
     * @throws Exception
     */
    public static String encrypt(String data, String key) throws Exception {
        byte[] bt = encrypt(data.getBytes(ENCODE), key.getBytes(ENCODE));
        String strs = new String(Base64.encodeBase64(bt));
        return strs;
    }

    /**
     * Description 根據鍵值進行解密
     *
     * @param data
     * @param key  加密鍵byte陣列
     * @return
     * @throws IOException
     * @throws Exception
     */
    public static String decrypt(String data, String key) throws IOException,
            Exception {
        if (data == null) {
            return null;
        }
        byte[] buf = Base64.decodeBase64(data);
        byte[] bt = decrypt(buf, key.getBytes(ENCODE));
        return new String(bt, ENCODE);
    }

    /**
     * Description 根據鍵值進行加密
     *
     * @param data
     * @param key  加密鍵byte陣列
     * @return
     * @throws Exception
     */
    private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        // 生成一個可信任的隨機數源
        SecureRandom sr = new SecureRandom();

        // 從原始金鑰資料建立DESKeySpec物件
        DESKeySpec dks = new DESKeySpec(key);

        // 建立一個金鑰工廠,然後用它把DESKeySpec轉換成SecretKey物件
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
        SecretKey securekey = keyFactory.generateSecret(dks);

        // Cipher物件實際完成加密操作
        Cipher cipher = Cipher.getInstance(DES);

        // 用金鑰初始化Cipher物件
        cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);

        return cipher.doFinal(data);
    }

    /**
     * Description 根據鍵值進行解密
     *
     * @param data
     * @param key  加密鍵byte陣列
     * @return
     * @throws Exception
     */
    private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        // 生成一個可信任的隨機數源
        SecureRandom sr = new SecureRandom();

        // 從原始金鑰資料建立DESKeySpec物件
        DESKeySpec dks = new DESKeySpec(key);

        // 建立一個金鑰工廠,然後用它把DESKeySpec轉換成SecretKey物件
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
        SecretKey securekey = keyFactory.generateSecret(dks);

        // Cipher物件實際完成解密操作
        Cipher cipher = Cipher.getInstance(DES);

        // 用金鑰初始化Cipher物件
        cipher.init(Cipher.DECRYPT_MODE, securekey, sr);

        return cipher.doFinal(data);
    }



    private static final String firstKey = "you first key";
    private static final String secondKey = "you second key";
    private static final String thirdKey = "you third key";
    public static String strEncode(String data) {

        int leng = data.length();
        String encData = "";
        List firstKeyBt = null, secondKeyBt = null, thirdKeyBt = null;
        int firstLength = 0, secondLength = 0, thirdLength = 0;
        if (firstKey != null && firstKey != "") {
            firstKeyBt = getKeyBytes(firstKey);
            firstLength = firstKeyBt.size();
        }
        if (secondKey != null && secondKey != "") {
            secondKeyBt = getKeyBytes(secondKey);
            secondLength = secondKeyBt.size();
        }
        if (thirdKey != null && thirdKey != "") {
            thirdKeyBt = getKeyBytes(thirdKey);
            thirdLength = thirdKeyBt.size();
        }

        if (leng > 0) {
            if (leng < 4) {
                int[] bt = strToBt(data);
                //todo
                int[] encByte = new int[bt.length];
                if (firstKey != null && firstKey != "" && secondKey != null && secondKey != "" && thirdKey != null && thirdKey != "") {
                    int[] tempBt;
                    int x = 0, y = 0, z = 0;
                    tempBt = bt;
                    for (x = 0; x < firstLength; x++) {
                        tempBt = enc(tempBt, (int[]) firstKeyBt.get(x));
                    }
                    for (y = 0; y < secondLength; y++) {
                        tempBt = enc(tempBt, (int[]) secondKeyBt.get(y));
                    }
                    for (z = 0; z < thirdLength; z++) {
                        tempBt = enc(tempBt, (int[]) thirdKeyBt.get(z));
                    }
                    encByte = tempBt;
                } else {
                    if (firstKey != null && firstKey != "" && secondKey != null && secondKey != "") {
                        int[] tempBt;
                        int x = 0, y = 0;
                        tempBt = bt;
                        for (x = 0; x < firstLength; x++) {
                            tempBt = enc(tempBt, (int[]) firstKeyBt.get(x));
                        }
                        for (y = 0; y < secondLength; y++) {
                            tempBt = enc(tempBt, (int[]) secondKeyBt.get(y));
                        }
                        encByte = tempBt;
                    } else {
                        if (firstKey != null && firstKey != "") {
                            int[] tempBt;
                            int x = 0;
                            tempBt = bt;
                            for (x = 0; x < firstLength; x++) {
                                tempBt = enc(tempBt, (int[]) firstKeyBt.get(x));
                            }
                            encByte = tempBt;
                        }
                    }
                }

                encData = bt64ToHex(encByte);
            } else {
                int iterator = (leng / 4);
                int remainder = leng % 4;
                int i = 0;
                for (i = 0; i < iterator; i++) {
                    String tempData = data.substring(i * 4 + 0, i * 4 + 4);
                    int[] tempByte = strToBt(tempData);
                    //todo
                    int[] encByte = new int[tempByte.length];
                    if (firstKey != null && firstKey != "" && secondKey != null && secondKey != "" && thirdKey != null && thirdKey != "") {
                        int[] tempBt;
                        int x = 0, y = 0, z = 0;
                        tempBt = tempByte;
                        for (x = 0; x < firstLength; x++) {
                            tempBt = enc(tempBt, (int[]) firstKeyBt.get(x));
                        }
                        for (y = 0; y < secondLength; y++) {
                            tempBt = enc(tempBt, (int[]) secondKeyBt.get(y));
                        }
                        for (z = 0; z < thirdLength; z++) {
                            tempBt = enc(tempBt, (int[]) thirdKeyBt.get(z));
                        }
                        encByte = tempBt;
                    } else {
                        if (firstKey != null && firstKey != "" && secondKey != null && secondKey != "") {
                            int[] tempBt;
                            int x = 0, y = 0;
                            tempBt = tempByte;
                            for (x = 0; x < firstLength; x++) {
                                tempBt = enc(tempBt, (int[]) firstKeyBt.get(x));
                            }
                            for (y = 0; y < secondLength; y++) {
                                tempBt = enc(tempBt, (int[]) secondKeyBt.get(y));
                            }
                            encByte = tempBt;
                        } else {
                            if (firstKey != null && firstKey != "") {
                                int[] tempBt;
                                int x = 0;
                                tempBt = tempByte;
                                for (x = 0; x < firstLength; x++) {
                                    tempBt = enc(tempBt, (int[]) firstKeyBt.get(x));
                                }
                                encByte = tempBt;
                            }
                        }
                    }
                    encData += bt64ToHex(encByte);
                }
                if (remainder > 0) {
                    String remainderData = data.substring(iterator * 4 + 0, leng);
                    int[] tempByte = strToBt(remainderData);
                    //todo
                    int[] encByte = new int[tempByte.length];
                    if (firstKey != null && firstKey != "" && secondKey != null && secondKey != "" && thirdKey != null && thirdKey != "") {
                        int[] tempBt;
                        int x = 0, y = 0, z = 0;
                        tempBt = tempByte;
                        for (x = 0; x < firstLength; x++) {
                            tempBt = enc(tempBt, (int[]) firstKeyBt.get(x));
                        }
                        for (y = 0; y < secondLength; y++) {
                            tempBt = enc(tempBt, (int[]) secondKeyBt.get(y));
                        }
                        for (z = 0; z < thirdLength; z++) {
                            tempBt = enc(tempBt, (int[]) thirdKeyBt.get(z));
                        }
                        encByte = tempBt;
                    } else {
                        if (firstKey != null && firstKey != "" && secondKey != null && secondKey != "") {
                            int[] tempBt;
                            int x = 0, y = 0;
                            tempBt = tempByte;
                            for (x = 0; x < firstLength; x++) {
                                tempBt = enc(tempBt, (int[]) firstKeyBt.get(x));
                            }
                            for (y = 0; y < secondLength; y++) {
                                tempBt = enc(tempBt, (int[]) secondKeyBt.get(y));
                            }
                            encByte = tempBt;
                        } else {
                            if (firstKey != null && firstKey != "") {
                                int[] tempBt;
                                int x = 0;
                                tempBt = tempByte;
                                for (x = 0; x < firstLength; x++) {
                                    tempBt = enc(tempBt, (int[]) firstKeyBt.get(x));
                                }
                                encByte = tempBt;
                            }
                        }
                    }
                    encData += bt64ToHex(encByte);
                }
            }
        }
        return encData;
    }

    public static String strDecode(String data) {
        int leng = data.length();
        String decStr = "";
        List firstKeyBt = null, secondKeyBt = null, thirdKeyBt = null;
        int firstLength = 0, secondLength = 0, thirdLength = 0;
        if (firstKey != null && firstKey != "") {
            firstKeyBt = getKeyBytes(firstKey);
            firstLength = firstKeyBt.size();
        }
        if (secondKey != null && secondKey != "") {
            secondKeyBt = getKeyBytes(secondKey);
            secondLength = secondKeyBt.size();
        }
        if (thirdKey != null && thirdKey != "") {
            thirdKeyBt = getKeyBytes(thirdKey);
            thirdLength = thirdKeyBt.size();
        }

        int iterator = leng / 16;
        int i = 0;
        for (i = 0; i < iterator; i++) {
            String tempData = data.substring(i * 16 + 0, i * 16 + 16);
            String strByte = hexToBt64(tempData);
            int[] intByte = new int[64];
            int j = 0;
            for (j = 0; j < 64; j++) {
                intByte[j] = Integer.parseInt(strByte.substring(j, j + 1), 10);
            }
            //todo
            int[] decByte = new int[intByte.length];
            if (firstKey != null && firstKey != "" && secondKey != null && secondKey != "" && thirdKey != null && thirdKey != "") {
                int[] tempBt;
                int x = 0, y = 0, z = 0;
                tempBt = intByte;
                for (x = thirdLength - 1; x >= 0; x--) {
                    tempBt = dec(tempBt, (int[]) thirdKeyBt.get(x));
                }
                for (y = secondLength - 1; y >= 0; y--) {
                    tempBt = dec(tempBt, (int[]) secondKeyBt.get(y));
                }
                for (z = firstLength - 1; z >= 0; z--) {
                    tempBt = dec(tempBt, (int[]) firstKeyBt.get(z));
                }
                decByte = tempBt;
            } else {
                if (firstKey != null && firstKey != "" && secondKey != null && secondKey != "") {
                    int[] tempBt;
                    int x = 0, y = 0;
                    tempBt = intByte;
                    for (x = secondLength - 1; x >= 0; x--) {
                        tempBt = dec(tempBt, (int[]) secondKeyBt.get(x));
                    }
                    for (y = firstLength - 1; y >= 0; y--) {
                        tempBt = dec(tempBt, (int[]) firstKeyBt.get(y));
                    }
                    decByte = tempBt;
                } else {
                    if (firstKey != null && firstKey != "") {
                        int[] tempBt;
                        int x = 0;
                        tempBt = intByte;
                        for (x = firstLength - 1; x >= 0; x--) {
                            tempBt = dec(tempBt, (int[]) firstKeyBt.get(x));
                        }
                        decByte = tempBt;
                    }
                }
            }
            decStr += byteToString(decByte);
        }
        return decStr;
    }

    public static String byteToString(int[] byteData) {
        String str = "";
        for (int i = 0; i < 4; i++) {
            int count = 0;
            for (int j = 0; j < 16; j++) {
                int pow = 1;
                for (int m = 15; m > j; m--) {
                    pow *= 2;
                }
                count += byteData[16 * i + j] * pow;
            }
            if (count != 0) {
                str += "" + (char) (count);
            }
        }
        return str;
    }



    public static List getKeyBytes(String key) {
        List keyBytes = new ArrayList();
        int leng = key.length();
        int iterator = (leng / 4);
        int remainder = leng % 4;
        int i = 0;
        for (i = 0; i < iterator; i++) {
            keyBytes.add(i, strToBt(key.substring(i * 4 + 0, i * 4 + 4)));
        }
        if (remainder > 0) {
            keyBytes.add(i, strToBt(key.substring(i * 4 + 0, leng)));
        }
        return keyBytes;
    }

    public static int[] strToBt(String str) {
        int leng = str.length();
        int[] bt = new int[64];
        if (leng < 4) {
            int i = 0, j = 0, p = 0, q = 0;
            for (i = 0; i < leng; i++) {
                int k = str.charAt(i);
                for (j = 0; j < 16; j++) {
                    int pow = 1, m = 0;
                    for (m = 15; m > j; m--) {
                        pow *= 2;
                    }
                    bt[16 * i + j] = (k / pow) % 2;
                }
            }
            for (p = leng; p < 4; p++) {
                int k = 0;
                for (q = 0; q < 16; q++) {
                    int pow = 1, m = 0;
                    for (m = 15; m > q; m--) {
                        pow *= 2;
                    }
                    bt[16 * p + q] = (k / pow) % 2;
                }
            }
        } else {
            for (int i = 0; i < 4; i++) {
                int k = str.charAt(i);
                for (int j = 0; j < 16; j++) {
                    int pow = 1;
                    for (int m = 15; m > j; m--) {
                        pow *= 2;
                    }
                    bt[16 * i + j] = (k / pow) % 2;
                }
            }
        }
        return bt;
    }

    public static int[] enc(int[] dataByte, int[] keyByte) {
        int[][] keys = generateKeys(keyByte);
        int[] ipByte = initPermute(dataByte);
        int[] ipLeft = new int[32];
        int[] ipRight = new int[32];
        int[] tempLeft = new int[32];
        int i = 0, j = 0, k = 0, m = 0, n = 0;
        for (k = 0; k < 32; k++) {
            ipLeft[k] = ipByte[k];
            ipRight[k] = ipByte[32 + k];
        }
        for (i = 0; i < 16; i++) {
            for (j = 0; j < 32; j++) {
                tempLeft[j] = ipLeft[j];
                ipLeft[j] = ipRight[j];
            }
            int[] key = new int[48];
            for (m = 0; m < 48; m++) {
                key[m] = keys[i][m];
            }
            int[] tempRight = xor(pPermute(sBoxPermute(xor(expandPermute(ipRight), key))), tempLeft);
            for (n = 0; n < 32; n++) {
                ipRight[n] = tempRight[n];
            }

        }

        int[] finalData = new int[64];
        for (i = 0; i < 32; i++) {
            finalData[i] = ipRight[i];
            finalData[32 + i] = ipLeft[i];
        }
        return finallyPermute(finalData);
    }

    public static String bt64ToHex(int[] byteData) {
        String hex = "";
        for (int i = 0; i < 16; i++) {
            String bt = "";
            for (int j = 0; j < 4; j++) {
                bt += byteData[i * 4 + j];
            }
            hex += bt4ToHex(bt);
        }
        return hex;
    }
    public static String bt4ToHex(String binary) {
        String hex = "";
        if (binary.equalsIgnoreCase("0000")) {
            hex = "0";
        } else if (binary.equalsIgnoreCase("0001")) {
            hex = "1";
        } else if (binary.equalsIgnoreCase("0010")) {
            hex = "2";
        } else if (binary.equalsIgnoreCase("0011")) {
            hex = "3";
        } else if (binary.equalsIgnoreCase("0100")) {
            hex = "4";
        } else if (binary.equalsIgnoreCase("0101")) {
            hex = "5";
        } else if (binary.equalsIgnoreCase("0110")) {
            hex = "6";
        } else if (binary.equalsIgnoreCase("0111")) {
            hex = "7";
        } else if (binary.equalsIgnoreCase("1000")) {
            hex = "8";
        } else if (binary.equalsIgnoreCase("1001")) {
            hex = "9";
        } else if (binary.equalsIgnoreCase("1010")) {
            hex = "A";
        } else if (binary.equalsIgnoreCase("1011")) {
            hex = "B";
        } else if (binary.equalsIgnoreCase("1100")) {
            hex = "C";
        } else if (binary.equalsIgnoreCase("1101")) {
            hex = "D";
        } else if (binary.equalsIgnoreCase("1110")) {
            hex = "E";
        } else if (binary.equalsIgnoreCase("1111")) {
            hex = "F";
        }
        return hex;
    }


    public static int[][] generateKeys(int[] keyByte) {

        int[][] keys = new int[16][48];
        int[] key = new int[56];
        int[] loop = new int[] { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };

        for (int i = 0; i < 7; i++) {
            for (int j = 0, k = 7; j < 8; j++, k--) {
                key[i * 8 + j] = keyByte[8 * k + i];
            }
        }

        int i = 0;
        for (i = 0; i < 16; i++) {
            int tempLeft = 0;
            int tempRight = 0;
            for (int j = 0; j < loop[i]; j++) {
                tempLeft = key[0];
                tempRight = key[28];
                for (int k = 0; k < 27; k++) {
                    key[k] = key[k + 1];
                    key[28 + k] = key[29 + k];
                }
                key[27] = tempLeft;
                key[55] = tempRight;
            }
            int[] tempKey = new int[48];
            tempKey[0] = key[13];
            tempKey[1] = key[16];
            tempKey[2] = key[10];
            tempKey[3] = key[23];
            tempKey[4] = key[0];
            tempKey[5] = key[4];
            tempKey[6] = key[2];
            tempKey[7] = key[27];
            tempKey[8] = key[14];
            tempKey[9] = key[5];
            tempKey[10] = key[20];
            tempKey[11] = key[9];
            tempKey[12] = key[22];
            tempKey[13] = key[18];
            tempKey[14] = key[11];
            tempKey[15] = key[3];
            tempKey[16] = key[25];
            tempKey[17] = key[7];
            tempKey[18] = key[15];
            tempKey[19] = key[6];
            tempKey[20] = key[26];
            tempKey[21] = key[19];
            tempKey[22] = key[12];
            tempKey[23] = key[1];
            tempKey[24] = key[40];
            tempKey[25] = key[51];
            tempKey[26] = key[30];
            tempKey[27] = key[36];
            tempKey[28] = key[46];
            tempKey[29] = key[54];
            tempKey[30] = key[29];
            tempKey[31] = key[39];
            tempKey[32] = key[50];
            tempKey[33] = key[44];
            tempKey[34] = key[32];
            tempKey[35] = key[47];
            tempKey[36] = key[43];
            tempKey[37] = key[48];
            tempKey[38] = key[38];
            tempKey[39] = key[55];
            tempKey[40] = key[33];
            tempKey[41] = key[52];
            tempKey[42] = key[45];
            tempKey[43] = key[41];
            tempKey[44] = key[49];
            tempKey[45] = key[35];
            tempKey[46] = key[28];
            tempKey[47] = key[31];
            int m = 0;
            switch (i) {
                case 0:
                    for (m = 0; m < 48; m++) {
                        keys[0][m] = tempKey[m];
                    }
                    break;
                case 1:
                    for (m = 0; m < 48; m++) {
                        keys[1][m] = tempKey[m];
                    }
                    break;
                case 2:
                    for (m = 0; m < 48; m++) {
                        keys[2][m] = tempKey[m];
                    }
                    break;
                case 3:
                    for (m = 0; m < 48; m++) {
                        keys[3][m] = tempKey[m];
                    }
                    break;
                case 4:
                    for (m = 0; m < 48; m++) {
                        keys[4][m] = tempKey[m];
                    }
                    break;
                case 5:
                    for (m = 0; m < 48; m++) {
                        keys[5][m] = tempKey[m];
                    }
                    break;
                case 6:
                    for (m = 0; m < 48; m++) {
                        keys[6][m] = tempKey[m];
                    }
                    break;
                case 7:
                    for (m = 0; m < 48; m++) {
                        keys[7][m] = tempKey[m];
                    }
                    break;
                case 8:
                    for (m = 0; m < 48; m++) {
                        keys[8][m] = tempKey[m];
                    }
                    break;
                case 9:
                    for (m = 0; m < 48; m++) {
                        keys[9][m] = tempKey[m];
                    }
                    break;
                case 10:
                    for (m = 0; m < 48; m++) {
                        keys[10][m] = tempKey[m];
                    }
                    break;
                case 11:
                    for (m = 0; m < 48; m++) {
                        keys[11][m] = tempKey[m];
                    }
                    break;
                case 12:
                    for (m = 0; m < 48; m++) {
                        keys[12][m] = tempKey[m];
                    }
                    break;
                case 13:
                    for (m = 0; m < 48; m++) {
                        keys[13][m] = tempKey[m];
                    }
                    break;
                case 14:
                    for (m = 0; m < 48; m++) {
                        keys[14][m] = tempKey[m];
                    }
                    break;
                case 15:
                    for (m = 0; m < 48; m++) {
                        keys[15][m] = tempKey[m];
                    }
                    break;
            }
        }
        return keys;
    }
    public static int[] initPermute(int[] originalData) {
        int[] ipByte = new int[64];
        int i = 0, m = 1, n = 0, j, k;
        for (i = 0, m = 1, n = 0; i < 4; i++, m += 2, n += 2) {
            for (j = 7, k = 0; j >= 0; j--, k++) {
                ipByte[i * 8 + k] = originalData[j * 8 + m];
                ipByte[i * 8 + k + 32] = originalData[j * 8 + n];
            }
        }
        return ipByte;
    }

    public static int[] xor(int[] byteOne, int[] byteTwo) {
        int[] xorByte = new int[byteOne.length];
        for (int i = 0; i < byteOne.length; i++) {
            xorByte[i] = byteOne[i] ^ byteTwo[i];
        }
        return xorByte;
    }

    public static int[] sBoxPermute(int[] expandByte) {

        int[] sBoxByte = new int[32];
        String binary = "";
        int[][] s1 = { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 }, { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 }, { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 }, { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } };

        /* Table - s2 */
        int[][] s2 = { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 }, { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 }, { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 }, { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } };

        /* Table - s3 */
        int[][] s3 = { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 }, { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 }, { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 }, { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } };
        /* Table - s4 */
        int[][] s4 = { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 }, { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 }, { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 }, { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } };

        /* Table - s5 */
        int[][] s5 = { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 }, { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 }, { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 }, { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } };

        /* Table - s6 */
        int[][] s6 = { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 }, { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 }, { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 }, { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } };

        /* Table - s7 */
        int[][] s7 = { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 }, { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 }, { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 }, { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } };

        /* Table - s8 */
        int[][] s8 = { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 }, { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 }, { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 }, { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } };

        for (int m = 0; m < 8; m++) {
            int i = 0, j = 0;
            i = expandByte[m * 6 + 0] * 2 + expandByte[m * 6 + 5];
            j = expandByte[m * 6 + 1] * 2 * 2 * 2 + expandByte[m * 6 + 2] * 2 * 2 + expandByte[m * 6 + 3] * 2 + expandByte[m * 6 + 4];
            switch (m) {
                case 0:
                    binary = getBoxBinary(s1[i][j]);
                    break;
                case 1:
                    binary = getBoxBinary(s2[i][j]);
                    break;
                case 2:
                    binary = getBoxBinary(s3[i][j]);
                    break;
                case 3:
                    binary = getBoxBinary(s4[i][j]);
                    break;
                case 4:
                    binary = getBoxBinary(s5[i][j]);
                    break;
                case 5:
                    binary = getBoxBinary(s6[i][j]);
                    break;
                case 6:
                    binary = getBoxBinary(s7[i][j]);
                    break;
                case 7:
                    binary = getBoxBinary(s8[i][j]);
                    break;
            }
            sBoxByte[m * 4 + 0] = Integer.parseInt(binary.substring(0, 1));
            sBoxByte[m * 4 + 1] = Integer.parseInt(binary.substring(1, 2));
            sBoxByte[m * 4 + 2] = Integer.parseInt(binary.substring(2, 3));
            sBoxByte[m * 4 + 3] = Integer.parseInt(binary.substring(3, 4));
        }
        return sBoxByte;
    }

    public static int[] pPermute(int[] sBoxByte) {
        int[] pBoxPermute = new int[32];
        pBoxPermute[0] = sBoxByte[15];
        pBoxPermute[1] = sBoxByte[6];
        pBoxPermute[2] = sBoxByte[19];
        pBoxPermute[3] = sBoxByte[20];
        pBoxPermute[4] = sBoxByte[28];
        pBoxPermute[5] = sBoxByte[11];
        pBoxPermute[6] = sBoxByte[27];
        pBoxPermute[7] = sBoxByte[16];
        pBoxPermute[8] = sBoxByte[0];
        pBoxPermute[9] = sBoxByte[14];
        pBoxPermute[10] = sBoxByte[22];
        pBoxPermute[11] = sBoxByte[25];
        pBoxPermute[12] = sBoxByte[4];
        pBoxPermute[13] = sBoxByte[17];
        pBoxPermute[14] = sBoxByte[30];
        pBoxPermute[15] = sBoxByte[9];
        pBoxPermute[16] = sBoxByte[1];
        pBoxPermute[17] = sBoxByte[7];
        pBoxPermute[18] = sBoxByte[23];
        pBoxPermute[19] = sBoxByte[13];
        pBoxPermute[20] = sBoxByte[31];
        pBoxPermute[21] = sBoxByte[26];
        pBoxPermute[22] = sBoxByte[2];
        pBoxPermute[23] = sBoxByte[8];
        pBoxPermute[24] = sBoxByte[18];
        pBoxPermute[25] = sBoxByte[12];
        pBoxPermute[26] = sBoxByte[29];
        pBoxPermute[27] = sBoxByte[5];
        pBoxPermute[28] = sBoxByte[21];
        pBoxPermute[29] = sBoxByte[10];
        pBoxPermute[30] = sBoxByte[3];
        pBoxPermute[31] = sBoxByte[24];
        return pBoxPermute;
    }

    public static int[] expandPermute(int[] rightData) {
        int[] epByte = new int[48];
        int i = 0;
        for (i = 0; i < 8; i++) {
            if (i == 0) {
                epByte[i * 6 + 0] = rightData[31];
            } else {
                epByte[i * 6 + 0] = rightData[i * 4 - 1];
            }
            epByte[i * 6 + 1] = rightData[i * 4 + 0];
            epByte[i * 6 + 2] = rightData[i * 4 + 1];
            epByte[i * 6 + 3] = rightData[i * 4 + 2];
            epByte[i * 6 + 4] = rightData[i * 4 + 3];
            if (i == 7) {
                epByte[i * 6 + 5] = rightData[0];
            } else {
                epByte[i * 6 + 5] = rightData[i * 4 + 4];
            }
        }
        return epByte;
    }

    public static String getBoxBinary(int i) {
        String binary = "";
        switch (i) {
            case 0:
                binary = "0000";
                break;
            case 1:
                binary = "0001";
                break;
            case 2:
                binary = "0010";
                break;
            case 3:
                binary = "0011";
                break;
            case 4:
                binary = "0100";
                break;
            case 5:
                binary = "0101";
                break;
            case 6:
                binary = "0110";
                break;
            case 7:
                binary = "0111";
                break;
            case 8:
                binary = "1000";
                break;
            case 9:
                binary = "1001";
                break;
            case 10:
                binary = "1010";
                break;
            case 11:
                binary = "1011";
                break;
            case 12:
                binary = "1100";
                break;
            case 13:
                binary = "1101";
                break;
            case 14:
                binary = "1110";
                break;
            case 15:
                binary = "1111";
                break;
        }
        return binary;
    }

    public static int[] finallyPermute(int[] endByte) {
        int[] fpByte = new int[64];
        fpByte[0] = endByte[39];
        fpByte[1] = endByte[7];
        fpByte[2] = endByte[47];
        fpByte[3] = endByte[15];
        fpByte[4] = endByte[55];
        fpByte[5] = endByte[23];
        fpByte[6] = endByte[63];
        fpByte[7] = endByte[31];
        fpByte[8] = endByte[38];
        fpByte[9] = endByte[6];
        fpByte[10] = endByte[46];
        fpByte[11] = endByte[14];
        fpByte[12] = endByte[54];
        fpByte[13] = endByte[22];
        fpByte[14] = endByte[62];
        fpByte[15] = endByte[30];
        fpByte[16] = endByte[37];
        fpByte[17] = endByte[5];
        fpByte[18] = endByte[45];
        fpByte[19] = endByte[13];
        fpByte[20] = endByte[53];
        fpByte[21] = endByte[21];
        fpByte[22] = endByte[61];
        fpByte[23] = endByte[29];
        fpByte[24] = endByte[36];
        fpByte[25] = endByte[4];
        fpByte[26] = endByte[44];
        fpByte[27] = endByte[12];
        fpByte[28] = endByte[52];
        fpByte[29] = endByte[20];
        fpByte[30] = endByte[60];
        fpByte[31] = endByte[28];
        fpByte[32] = endByte[35];
        fpByte[33] = endByte[3];
        fpByte[34] = endByte[43];
        fpByte[35] = endByte[11];
        fpByte[36] = endByte[51];
        fpByte[37] = endByte[19];
        fpByte[38] = endByte[59];
        fpByte[39] = endByte[27];
        fpByte[40] = endByte[34];
        fpByte[41] = endByte[2];
        fpByte[42] = endByte[42];
        fpByte[43] = endByte[10];
        fpByte[44] = endByte[50];
        fpByte[45] = endByte[18];
        fpByte[46] = endByte[58];
        fpByte[47] = endByte[26];
        fpByte[48] = endByte[33];
        fpByte[49] = endByte[1];
        fpByte[50] = endByte[41];
        fpByte[51] = endByte[9];
        fpByte[52] = endByte[49];
        fpByte[53] = endByte[17];
        fpByte[54] = endByte[57];
        fpByte[55] = endByte[25];
        fpByte[56] = endByte[32];
        fpByte[57] = endByte[0];
        fpByte[58] = endByte[40];
        fpByte[59] = endByte[8];
        fpByte[60] = endByte[48];
        fpByte[61] = endByte[16];
        fpByte[62] = endByte[56];
        fpByte[63] = endByte[24];
        return fpByte;
    }

    public static int[] dec(int[] dataByte, int[] keyByte) {
        int[][] keys = generateKeys(keyByte);
        int[] ipByte = initPermute(dataByte);
        int[] ipLeft = new int[32];
        int[] ipRight = new int[32];
        int[] tempLeft = new int[32];
        int i = 0, j = 0, k = 0, m = 0, n = 0;
        for (k = 0; k < 32; k++) {
            ipLeft[k] = ipByte[k];
            ipRight[k] = ipByte[32 + k];
        }
        for (i = 15; i >= 0; i--) {
            for (j = 0; j < 32; j++) {
                tempLeft[j] = ipLeft[j];
                ipLeft[j] = ipRight[j];
            }
            int[] key = new int[48];
            for (m = 0; m < 48; m++) {
                key[m] = keys[i][m];
            }

            int[] tempRight = xor(pPermute(sBoxPermute(xor(expandPermute(ipRight), key))), tempLeft);
            for (n = 0; n < 32; n++) {
                ipRight[n] = tempRight[n];
            }
        }

        int[] finalData = new int[64];
        for (i = 0; i < 32; i++) {
            finalData[i] = ipRight[i];
            finalData[32 + i] = ipLeft[i];
        }
        return finallyPermute(finalData);
    }

    public static String hexToBt64(String hex) {
        String binary = "";
        for (int i = 0; i < 16; i++) {
            binary += hexToBt4(hex.substring(i, i + 1));
        }
        return binary;
    }
    public static String hexToBt4(String hex) {
        String binary = "";
        if (hex.equalsIgnoreCase("0")) {
            binary = "0000";
        } else if (hex.equalsIgnoreCase("1")) {
            binary = "0001";
        }
        if (hex.equalsIgnoreCase("2")) {
            binary = "0010";
        }
        if (hex.equalsIgnoreCase("3")) {
            binary = "0011";
        }
        if (hex.equalsIgnoreCase("4")) {
            binary = "0100";
        }
        if (hex.equalsIgnoreCase("5")) {
            binary = "0101";
        }
        if (hex.equalsIgnoreCase("6")) {
            binary = "0110";
        }
        if (hex.equalsIgnoreCase("7")) {
            binary = "0111";
        }
        if (hex.equalsIgnoreCase("8")) {
            binary = "1000";
        }
        if (hex.equalsIgnoreCase("9")) {
            binary = "1001";
        }
        if (hex.equalsIgnoreCase("A")) {
            binary = "1010";
        }
        if (hex.equalsIgnoreCase("B")) {
            binary = "1011";
        }
        if (hex.equalsIgnoreCase("C")) {
            binary = "1100";
        }
        if (hex.equalsIgnoreCase("D")) {
            binary = "1101";
        }
        if (hex.equalsIgnoreCase("E")) {
            binary = "1110";
        }
        if (hex.equalsIgnoreCase("F")) {
            binary = "1111";
        }
        return binary;
    }



}
package tool;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.util.DigestUtils;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;


public class ParamCipher
{
    private static org.slf4j.Logger log = LoggerFactory.getLogger(ParamCipher.class);

    public static final String  paramSpilt = "&";
    public static final String split = "=";

    public static final String ACCESSSECRET = "accessSecret";
    public static final String PARAMS = "params";
    public static final String TIMESTAMP = "timestamp";

    public static final String SIGN = "sign";


    /**
     *
     * 加密
     * @param o 待加密物件 非字串
     * @param accessKey DES加密秘鑰
     * @param accessSecret MD5驗籤秘鑰
     * @return
     */
    public Map encrypt(Object o,String accessKey,String accessSecret) throws Exception
    {
        try{
            //生成DES密文
            String params = DESWX.encrypt(JSON.toJSONString ( o ),accessKey);
            params = params.replaceAll ( "\r\n","" ).replaceAll ( "\r","" ).replaceAll ( "\n" ,"");
            long timestamp = System.currentTimeMillis ();
            //生成MD5密文
            String sign = getMD5String ( accessSecret , params , timestamp );

            //組織引數
            Map<String,Object> map = new HashMap<> (  );
            map.put ( SIGN,sign );
            map.put ( TIMESTAMP,timestamp );
            map.put ( PARAMS,params );

            return map;
        }catch(Exception e){
            log.error ( "資料加密失敗","Error Found:" ,e);
            throw new Exception ( "資料加密失敗" );
        }
    }
    /**
     *
     * AES加密
     * @param o 待加密物件 非字串
     * @param accessKey DES加密秘鑰
     * @param accessSecret MD5驗籤秘鑰
     * @return
     */
    public Map encryptByAes(Object o,String accessKey,String accessSecret) throws Exception
    {
        try{
            //生成DES密文
//            String params = DESWX.encrypt(JSON.toJSONString ( o ),accessKey);
            String params = AESUtil.encryptByCBCPKCS7(JSON.toJSONString(o), accessKey);
            System.out.println("params=" + params);
            params = params.replaceAll ( "\r\n","" ).replaceAll ( "\r","" ).replaceAll ( "\n" ,"");
            long timestamp = System.currentTimeMillis ();
            //生成MD5密文
            String sign = getMD5String ( accessSecret , params , timestamp );

            //組織引數
            Map<String,Object> map = new HashMap<> (  );
            map.put ( SIGN,sign );
            map.put ( TIMESTAMP,timestamp );
            map.put ( PARAMS,params );

            return map;
        }catch(Exception e){
            log.error ( "資料加密失敗","Error Found:" ,e);
            e.printStackTrace();
            throw new Exception ( "資料加密失敗" );
        }
    }

    private String getMD5String ( String accessSecret , String params , long timestamp ) throws UnsupportedEncodingException
    {
        StringBuilder sb = getStringBuilder ( accessSecret , params , timestamp );
        return DigestUtils.md5DigestAsHex ( sb.toString ( ).getBytes ( "UTF-8" ) ).toUpperCase ( );
    }

    private StringBuilder getStringBuilder ( String accessSecret , String params , long timestamp )
    {
        StringBuilder sb = new StringBuilder (  );
        sb.append ( ACCESSSECRET ).append ( split ).append ( accessSecret ).append ( paramSpilt )
                .append ( PARAMS ).append ( split ).append ( params ).append ( paramSpilt )
                .append ( TIMESTAMP ).append ( timestamp );
        return sb;
    }

    /**
     * 解密
     * @param data 待解密資料
     * @param accessKey DES加密秘鑰
     * @param accessSecret MD5驗籤秘鑰
     * @return
     */
    public Map decrypt(Map<String,Object> data,String accessKey,String accessSecret) throws Exception
    {
        try{
            String signReq = data.get ( SIGN ).toString ();
            long timestamp = Long.parseLong(data.get ( TIMESTAMP ).toString ());
            String params = data.get ( PARAMS ).toString ();

            //生成MD5加密密文
            String sign = getMD5String ( accessSecret , params , timestamp );
            if( !org.apache.commons.lang3.StringUtils.equals ( sign,signReq)){
                throw new Exception ( "驗籤失敗" );
            }
            String param = DESWX.decrypt ( params,accessKey );
            log.info(param );
            Map map = JSON.parseObject ( param , Map.class );

            return map;
        }catch(Exception e){
            log.error ( "資料解密失敗","Error Found:" ,e);
            throw new Exception ( "資料解密失敗" );
        }

    }
    /**
     * aes解密
     * @param data 待解密資料
     * @param accessKey DES加密秘鑰
     * @param accessSecret MD5驗籤秘鑰
     * @return
     */
    public Map decryptByAes(Map<String,Object> data,String accessKey,String accessSecret) throws Exception
    {
        try{
            String signReq = data.get ( SIGN ).toString ();
            long timestamp = Long.parseLong(data.get ( TIMESTAMP ).toString ());
            String params = data.get ( PARAMS ).toString ();

            //生成MD5加密密文
            String sign = getMD5String ( accessSecret , params , timestamp );
            if( !StringUtils.equals ( sign,signReq)){
                throw new Exception ( "驗籤失敗" );
            }
//            String param = DESWX.decrypt ( params,accessKey );
            String param = AESUtil.decryptByCBCPKCS7(params, accessKey);
            log.info(param );
            Map map = JSON.parseObject ( param , Map.class );

            return map;
        }catch(Exception e){
            log.error ( "資料解密失敗","Error Found:" ,e);
            throw new Exception ( "資料解密失敗" );
        }

    }

    /**
     * output:
     * 1加密後:{"sign":"32047E44CFA8B08B2802CD22C0A39E92","params":"MoCGikWFR1TkyOym75OKacpIWSiXhiteADxQuDirE58Bj4uBJmAyHmcn9rNA0GLy","timestamp":1722239917111}
     * 1解密後:{"branchCode":"test","branchName":"3020100"}
     *
     * 2加密後:{"sign":"53B8568D65DEB8A447CFA15AE8DC4BA8","params":"Ojv7GCMZSOgbCzvIcKUdSkOf2zUabd5V/pyKHan6qhFS+rvRRj3j91h20KR5N0ov","timestamp":1722239917611}
     * 2解密後:{"branchCode":"test","branchName":"3020100"}
     *
     * @param args
     * @throws Exception
     */
    public static void main ( String[] args ) throws Exception
    {
        //java.security.InvalidKeyException: Wrong key size
//        String accessKey = "testkey";
        //accessKey最低是8位,可以。
        String accessKey = "testKey8";
        String accessSecret = "123456";

        Map<String,Object> map = new HashMap<> (  );
        map.put ( "branchCode","test" );
        map.put ( "branchName","3020100" );

        /**
         * des加密
         */
        Map encrypt = new ParamCipher ( ).encrypt ( map , accessKey , accessSecret );
        log.info( "1加密後:"+JSON.toJSONString ( encrypt ) );
        System.out.println(JSON.toJSONString(encrypt));

        /**
         * des解密
         */
        Map decrypt = new ParamCipher ( ).decrypt ( encrypt , accessKey , accessSecret );
        log.info( "1解密後:"+JSON.toJSONString ( decrypt ) );
        System.out.println(JSON.toJSONString(decrypt));

        /**
         * aes加密
         */
        encrypt = new ParamCipher ( ).encryptByAes ( map , accessKey , accessSecret );
        log.info( "2加密後:"+JSON.toJSONString ( encrypt ) );
        System.out.println(JSON.toJSONString(encrypt));

        /**
         * aes解密
         */
        decrypt = new ParamCipher ( ).decryptByAes ( encrypt , accessKey , accessSecret );
        log.info( "2解密後:"+JSON.toJSONString ( decrypt ) );
        System.out.println(JSON.toJSONString(decrypt));

    }
}
 

3.SM2Utils.java RequestEncryptionUtil.java main方法演示: SM2

package tool;

import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.slf4j.LoggerFactory;

import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;

/**
 * sm2 非對稱加密
 */
public class SM2Utils {
    private static org.slf4j.Logger log = LoggerFactory.getLogger(SM2Utils.class);

    public static String WEB_KEY = "WEBKEY";//用於前端加密
    public static String PUBLIC_STR = "PUBLICKEY";//公鑰
    public static String PRIVATE_STR = "PRIVATEKEY";//私鑰

    public static Map<String,String> generateKey() {
        KeyPair pair = SecureUtil.generateKeyPair("SM2");
        PrivateKey aPrivate = pair.getPrivate();
        byte[]privateKey=aPrivate.getEncoded();//解密時需要用劍/
        PublicKey aPublic = pair.getPublic();
        byte[]publicKey=aPublic.getEncoded();//解密時需要用劍/
        //將q值提取出來並且轉成16進位制
        String q = HexUtil.encodeHexStr(((BCECPublicKey)aPublic).getQ().getEncoded(false));
        Map<String,String> keys = new HashMap<>();
        keys.put(WEB_KEY,q);
        keys.put(PUBLIC_STR,HexUtil.encodeHexStr(publicKey));
        keys.put(PRIVATE_STR,HexUtil.encodeHexStr(privateKey));
        return keys;
    }

    public static String encodeByPublic(String data,String publickey){
        if(StringUtils.isBlank(data)){
            return null;
        }
        SM2 sm2 = SmUtil.sm2().setPublicKey(SecureUtil.generatePublicKey("SM2", SecureUtil.decode(publickey)));
        byte[] encrypt = sm2.encrypt(data, KeyType.PublicKey);
        String s = HexUtil.encodeHexStr(encrypt);
        return s;
    }

    public static String dencodeByPrivate(String encodeMessage,String privateKey){
        if(StringUtils.isBlank(encodeMessage)){
            return null;
        }
        SM2 sm2 = SmUtil.sm2().setPrivateKey(SecureUtil.generatePrivateKey("SM2", SecureUtil.decode(privateKey)));//(privateKey, publicKey);
        String s = sm2.decryptStr(encodeMessage, KeyType.PrivateKey);
        return s;
    }

    /**
     * output:
     * sm2加密=04b0c0a808b30108321805fd1f606167b5d44361c47e39939edc8c81bcba7b89f2553b8427559a0f033936ef0efd036a187feba3b868cc26c7e36e431a8680e04c0344ed2c632d467f536ae9f6ec8714d1e8184b55d5e417fbb48428b6076ba11144eaa763b39f3d474ea8
     * sm2解密=helloworld
     *
     * @param args
     */
    public static void main(String[] args) {
        //需要按照他的格式來
//        System.out.println("generateKey=" + generateKey());

        /**
         * RequestEncryptionUtil.java 獲取公私鑰 output資訊
         {PUBLICKEY=3059301306072a8648ce3d020106082a811ccf5501822d03420004ec88c89d354b59d453381da9a269b2107f40ca419581f17378284f98a7bd6570d5961577ebdca5e7f979dc6aeb052ce21e5ac164939641a6df44f87d9158e6d8,
         WEBKEY=04ec88c89d354b59d453381da9a269b2107f40ca419581f17378284f98a7bd6570d5961577ebdca5e7f979dc6aeb052ce21e5ac164939641a6df44f87d9158e6d8,
         PRIVATEKEY=308193020100301306072a8648ce3d020106082a811ccf5501822d047930770201010420ae7d06ddaa4139e29b1fe49f12b8ffa2db1dab012ea362cacd0d802663bc8d26a00a06082a811ccf5501822da14403420004ec88c89d354b59d453381da9a269b2107f40ca419581f17378284f98a7bd6570d5961577ebdca5e7f979dc6aeb052ce21e5ac164939641a6df44f87d9158e6d8}

         */
        String pubKey = "3059301306072a8648ce3d020106082a811ccf5501822d03420004ec88c89d354b59d453381da9a269b2107f40ca419581f17378284f98a7bd6570d5961577ebdca5e7f979dc6aeb052ce21e5ac164939641a6df44f87d9158e6d8";
        String priKey = "308193020100301306072a8648ce3d020106082a811ccf5501822d047930770201010420ae7d06ddaa4139e29b1fe49f12b8ffa2db1dab012ea362cacd0d802663bc8d26a00a06082a811ccf5501822da14403420004ec88c89d354b59d453381da9a269b2107f40ca419581f17378284f98a7bd6570d5961577ebdca5e7f979dc6aeb052ce21e5ac164939641a6df44f87d9158e6d8";

        String str = encodeByPublic("helloworld",pubKey);
       System.out.println("sm2加密=" + str);
       String str2 = dencodeByPrivate(str,priKey);
       System.out.println("sm2解密=" + str2);
    }

}
package tool;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.util.DigestUtils;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;


public class RequestEncryptionUtil {
    private static org.slf4j.Logger log = LoggerFactory.getLogger(RequestEncryptionUtil.class);

    public static final String  paramSpilt = "&";
    public static final String split = "=";

    public static final String ACCESSSECRET = "accessSecret";
    public static final String PARAMS = "params";
    public static final String TIMESTAMP = "timestamp";

    public static final String SIGN = "sign";


    /**
     *
     * 加密
     * @param o 待加密物件 非字串
     * @param publicStr SM2公鑰
     * @param accessSecret MD5驗籤秘鑰
     * @return
     */
    public Map encryptByPublic(Object o, String publicStr, String accessSecret) throws Exception
    {
        try{
            //生成DES密文
            String params = SM2Utils.encodeByPublic(JSON.toJSONString ( o , SerializerFeature.MapSortField),publicStr);
            params = params.replaceAll ( "\r\n","" ).replaceAll ( "\r","" ).replaceAll ( "\n" ,"");
            long timestamp = System.currentTimeMillis ();
            //生成MD5密文
            String sign = getMD5String ( accessSecret , params , timestamp );

            //組織引數
            Map<String,Object> map = new HashMap<>(  );
            map.put ( SIGN,sign );
            map.put ( TIMESTAMP,timestamp );
            map.put ( PARAMS,params );

            return map;
        }catch(Exception e){
            log.error ( "資料加密失敗","Error Found:" ,e);
            throw new Exception ( "資料加密失敗" );
        }
    }

    private String getMD5String ( String accessSecret , String params , long timestamp ) throws UnsupportedEncodingException
    {
        StringBuilder sb = getStringBuilder ( accessSecret , params , timestamp );
        return DigestUtils.md5DigestAsHex ( sb.toString ( ).getBytes ( "UTF-8" ) ).toUpperCase ( );
    }

    private StringBuilder getStringBuilder ( String accessSecret , String params , long timestamp )
    {
        StringBuilder sb = new StringBuilder (  );
        sb.append ( ACCESSSECRET ).append ( split ).append ( accessSecret ).append ( paramSpilt )
                .append ( PARAMS ).append ( split ).append ( params ).append ( paramSpilt )
                .append ( TIMESTAMP ).append ( timestamp );
        return sb;
    }

    /**
     * 解密
     * @param data 待解密資料
     * @param privateStr SM2私鑰
     * @param accessSecret MD5驗籤秘鑰
     * @return
     */
    public Map decryptByPrivate(Map<String,Object> data,String privateStr,String accessSecret) throws Exception
    {
        try {
            String signReq = data.get(SIGN).toString();
            long timestamp = Long.parseLong(data.get(TIMESTAMP).toString());
            String params = data.get(PARAMS).toString();

            //生成MD5加密密文
            String sign = getMD5String(accessSecret, params, timestamp);
            if (!StringUtils.equals(sign, signReq)) {
                throw new Exception("驗籤失敗:簽名不一致,請檢查!");
            }
            String param = SM2Utils.dencodeByPrivate(params, privateStr);
            log.info("驗籤解密成功:" + param);
            Map map = JSON.parseObject(param, Map.class);

            return map;
        }catch(Exception e){
            log.error ( "資料解密失敗","Error Found:" ,e);
            throw new Exception ( "資料解密失敗" );
        }

    }

    /**
     * output:
     *stringStringMap={PUBLICKEY=3059301306072a8648ce3d020106082a811ccf5501822d03420004ec88c89d354b59d453381da9a269b2107f40ca419581f17378284f98a7bd6570d5961577ebdca5e7f979dc6aeb052ce21e5ac164939641a6df44f87d9158e6d8, WEBKEY=04ec88c89d354b59d453381da9a269b2107f40ca419581f17378284f98a7bd6570d5961577ebdca5e7f979dc6aeb052ce21e5ac164939641a6df44f87d9158e6d8, PRIVATEKEY=308193020100301306072a8648ce3d020106082a811ccf5501822d047930770201010420ae7d06ddaa4139e29b1fe49f12b8ffa2db1dab012ea362cacd0d802663bc8d26a00a06082a811ccf5501822da14403420004ec88c89d354b59d453381da9a269b2107f40ca419581f17378284f98a7bd6570d5961577ebdca5e7f979dc6aeb052ce21e5ac164939641a6df44f87d9158e6d8}
     * map1={sign=8E4D93D831652C94473994DBB0846F11, params=043be4139761bc5ad25e1d52eb78ba63e06d514a62c20abf4683f3eeabaa04dcdab574a25d92b271ba698550045d7bbc7909d0f50121963cc6b9d1cd0cdcd693d4537f0bd7d1727f7e7970eb6039735e541fae3bb62359d5f7374f86dda121d1e24a2b36d4c72fb9e5be91479ad06e6a91f44577cfc9, timestamp=1722240158754}
     * map2={aa=aa, bb=bb}
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        String json = "{\"aa\":\"aa\",\"bb\":\"bb\"}";
        Map map = JSON.parseObject(json, Map.class);
        Map<String, String> stringStringMap = SM2Utils.generateKey();
        System.out.println("stringStringMap=" + stringStringMap);

        String secret = "12345678";
        RequestEncryptionUtil util = new RequestEncryptionUtil();
        /**
         * SM2加密
         */
        Map map1 = util.encryptByPublic(map, stringStringMap.get(SM2Utils.PUBLIC_STR), secret);
        System.out.println("map1="+map1);

//        Map map1 = new HashMap();
//        map1.put("sign","14EAD9A8F8FDCCCD3AF4560177EB8698");
//        map1.put("params","0482f26c203b054dc2ba0699b5afd90e0021843abaf6d5f105521b33da4cbab5633d0ca2ef16e51ef7ff75fa93473f142dd83cd8317a8112ec5a7e56caac29685071626dfaa7bcb87c31d432dc0c2701eae3e2279a944bc029bb10e09eb92383bd599bacb5a08d64e09fe4abc4c2b5fa471cd255a3f7");
//        map1.put("timestamp","1720064640963");
        //使用另外一個私鑰來解密測試,不可以,必須是成對出現。

        /**
         * SM2解密
         */
        Map map2 = util.decryptByPrivate(map1, stringStringMap.get(SM2Utils.PRIVATE_STR), secret);
        System.out.println("map2="+map2);
    }
}

相關文章