加解密示例代码

package cpcn.dsp.institution.simulator.test;


import com.alibaba.fastjson.JSONObject;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.Enumeration;
import java.util.Random;

public class TestEncrypt {
    //公钥
    private static final String certificateFilepath = "/CPCN/DSP/DSPInstitutionSimulator/config/dsp/dsptest.cer";
    private static PublicKey publicKey;
    private static X509Certificate x509Certificate;
    private static String encryptSN;

    //私钥
    private static final String myKeystoreFilepath = "/CPCN/DSP/DSPInstitutionSimulator/config/dsp/test.pfx";
    private static final String myKeystorePassword = "cfca1234";
    private static PrivateKey privateKey;
    private static X509Certificate x509Certificate2;
    private static String signSN;
    //签名算法
    private static final String  algorithm = "SHA1withRSA";
    // 对称加密算法
    public static final String aes_algorithm = "AES/ECB/PKCS7Padding";
    // 非对称加密算法
    public static final String rsa_algorithm = "RSA/ECB/PKCS1Padding";

    private static String message = "";
    private static String signature = "";
    private static String dgtlenvlp = "";


    //随机密钥: AD21D6BCCE09A5044F87AF49540E1102
    public static void main(String[] args) throws Exception {
        String source = getSource2331();
        initEnv();

        createRequest(source);
        parseResult(dgtlenvlp, message, signature);

        byte[] decode = Base64.getDecoder().decode(
        "eyJNZXNzYWdlIjoi6Kej5p6Q5oql5paH6ZSZ6K+vIiwiQ29kZSI6IjIwMDMifQ==");
        System.out.println(new String(decode, "UTF-8"));


    }

    private static String getSource2331(){
        JSONObject json = new JSONObject();
        json.put("InstitutionID", "000020");
        json.put("TxCode", "2104");
        json.put("TxSN", "202005181330189983132331151");
        json.put("Remark", "");
        json.put("Name", "张三");
        json.put("IdentificationType","0");
        json.put("IdentificationNumber", "511102198310242028");


        // 转换为字符串
        return json.toString();
    }

    private static void createRequest(String source) throws Exception {
        // 随机秘钥
        String randomKeyData = randomHexString();
        System.out.println("随机密钥_source: " + randomKeyData);
        // RSA非对称加密
        dgtlenvlp = encryptByRSA(randomKeyData.getBytes("UTF-8"), publicKey);
        // AES256对称加密
        message =  encodeByAES(source, randomKeyData);
        // 签名
        signature = sign(source.getBytes("UTF-8"));
        System.out.println("dgtlenvlp:" + dgtlenvlp);
        System.out.println("message:" + message);
        System.out.println("signature:" + signature);


    }

    private static void parseResult(String requestDgtlEnvlp, String requestMessage, String sign) throws Exception {
        // RSA解密拿到随机密钥
        String randomKeyData2 = getDecryptKeyByteByRSA(requestDgtlEnvlp, privateKey);
        String randomKeyData3 = new String(hex2bytes(randomKeyData2), "UTF-8");
        System.out.println("随机密钥_return: " + randomKeyData3);
        String decryptMsg = decodeByAES(randomKeyData2, requestMessage);
        System.out.println("将消息解密后: " + decryptMsg);
        // 验签
        Boolean verify = verify(decryptMsg.getBytes("UTF-8"), sign);
        System.out.println("验签结果: " + verify);
    }

    /**
     * 初始化证书
     * @throws Exception
     */
    private static void initEnv() throws Exception {
        Security.addProvider(new BouncyCastleProvider());
        initPublicKey(certificateFilepath);
        initPfxKey(myKeystoreFilepath, myKeystorePassword);
    }

    /**
     * 生成AES密钥(随机密钥,len=32)
     * @return
     */
    private static String randomHexString() {
        int len = 32;
        StringBuffer result = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < len; i++) {
            result.append(Integer.toHexString(random.nextInt(16)));
        }
        return result.toString().toUpperCase();
    }

    /**
     * 签名
     * @param msg
     * @return
     * @throws Exception
     */
    private static String sign(byte[] msg) throws Exception {
        Signature signature = Signature.getInstance(algorithm);
        signature.initSign(privateKey);
        signature.update(msg);
        return bytes2hex(signature.sign());
    }



    /**
     * 验签
     * @param sign
     * @return
     * @throws Exception
     */
    private static Boolean verify (byte[] msg, String sign) throws Exception {
        byte[] signature = hex2bytes(sign);
        Signature sig = Signature.getInstance(algorithm);
        sig.initVerify(publicKey);
        sig.update(msg);
        return sig.verify(signature);
    }

    /**
     * RSA非对称加密
     * @param plainData
     * @param publicKey
     * @return
     * @throws Exception
     */
    private static String encryptByRSA(byte[] plainData, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] output = cipher.doFinal(plainData);
        return new String(Base64.getEncoder().encode(output));
    }

    /**
     * RSA非对称解密
     * @param signData
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static String getDecryptKeyByteByRSA(String signData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance(rsa_algorithm);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] output = cipher.doFinal(Base64.getDecoder().decode(signData));
        return bytes2hex(output);
    }

    /**
     * AES256对称加密
     * @param str
     * @param key
     * @return
     * @throws Exception
     */
    private static String encodeByAES(String str, String key) throws Exception {
        Cipher cipher = Cipher.getInstance(aes_algorithm, "BC");
        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); // 生成加密解密需要的Key
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);
        byte[] result = cipher.doFinal(str.getBytes("UTF-8"));
        return new String(Base64.getEncoder().encode(result));
    }

    /**
     * AES256对称解密
     * @param cipherText
     * @return
     * @throws Exception
     */
    public static String decodeByAES(String key, String cipherText) throws Exception {
        byte[] resByte = Base64.getDecoder().decode(cipherText);
        Cipher cipher = Cipher.getInstance(aes_algorithm, "BC");
        SecretKeySpec keySpec = new SecretKeySpec(hex2bytes(key), "AES"); // 生成加密解密需要的Key
        cipher.init(Cipher.DECRYPT_MODE, keySpec);
        byte[] decoded = cipher.doFinal(resByte);
        return new String(decoded, "UTF-8");
    }

    private static void initPublicKey(String file) throws Exception {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            x509Certificate = (X509Certificate) cf.generateCertificate(fis);
            publicKey = x509Certificate.getPublicKey();
            encryptSN = String.valueOf(x509Certificate.getSerialNumber());
            System.out.println("encryptSN:"+encryptSN );
        } finally {
            if (null != fis) {
                fis.close();
            }
        }
    }

    private static void initPfxKey(String pfxfilename, String password) throws Exception {
        // pfx格式的KeyStore的类型是pkcs#12
        KeyStore keyStore = KeyStore.getInstance("PKCS12");

        FileInputStream fis = new FileInputStream(pfxfilename);
        keyStore.load(fis, password.toCharArray());
        fis.close();
        Enumeration<String> aliases = keyStore.aliases();
        // 从pfx文件获得私钥和证书,BC jce和SUN不同,在SUN JCE中,公钥和私钥对应一个别名;而在BC中则对应不同的别名。
        String alias = (String) aliases.nextElement();
        // 获得用户证书私钥
        privateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());

        x509Certificate2 = (X509Certificate)keyStore.getCertificate(alias);

        signSN = String.valueOf(x509Certificate2.getSerialNumber());
        System.out.println("signSN:" + signSN);
    }
    private static String bytes2hex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        String b = "";
        if (null == bytes) {
            return null;
        }
        for (int i = 0; i < bytes.length; i++) {
            b = Integer.toHexString(bytes[i] & 0xFF);
            if (b.length() == 1) {
                result.append("0");
            }
            result.append(b);
        }
        return result.toString().toUpperCase();
    }

    public static byte[] hex2bytes(String hexStringParam) {
        String hexString = hexStringParam;

        // 转换成大写
        hexString = hexString.toUpperCase();

        // 计算字节数组的长度
        char[] chars = hexString.toCharArray();
        byte[] bytes = new byte[chars.length / 2];

        // 数组索引
        int index = 0;

        for (int i = 0; i < chars.length; i += 2) {
            byte newByte = 0x00;

            // 高位
            newByte |= char2byte(chars[i]);
            newByte <<= 4;

            // 低位
            newByte |= char2byte(chars[i + 1]);

            // 赋值
            bytes[index] = newByte;

            index++;
        }
        return bytes;
    }

    private static byte char2byte(char ch) {
        switch (ch) {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            case 'A':
            case 'B':
            case 'C':
            case 'D':
            case 'E':
            case 'F':
                return Byte.parseByte(String.valueOf(ch), 16);
            default:
                return 0x00;
        }
    }

}
Copyright © China Financial Digital Technology Co., Ltd. all right reserved,powered by Gitbook该文章修订时间: 2022-11-28 16:11:30

results matching ""

    No results matching ""