java RSA+AES实现接口验签和参数加密

原文链接:https://blog.csdn.net/qq_37469055/article/details/115188081

一:RSA非对称加密

RSA是一种常用的非对称加密算法,加密和加密使用不同的密钥,常用于要求安全性较高的加密场景,比如接口的验签和接口数据的加密与解密。与非对称加密算法对比,其安全性较高,但是加密性能却比较低,不适合高并发场景,一般只加密少量的数据。

二:AES对称加密

AES是一种最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的),加密和解密使用的是相同的密钥。其加密性能好,加密解密速度非常快,内存需求低,适用于经常发送数据的场合。

三:RSA+AES实现接口验签和请求参数的加密与解密

我们经常需要在我们自己开发的系统上,开发一些接口供第三方调用,那么这个时候,对我们接口的安全性要求就比较高了,尤其是那种需要传输比较私密的信息的时候,其对安全性的要求就更高了。

实现思路

调用方:

使用AES对称加密算法对业务请求参数进行加密后传输
使用RSA非对称加密算法对AES的密钥进行公钥加密后传输
使用RSA的私钥对请求参数进行签名
接收方:

获取到请求参数后,对参数进行验签和业务参数的解密
问题:为什么要对AES的密钥进行RSA公钥加密后传输?

AES是对称加密算法,加密和解密的密钥都是同一个,为了防止被别人恶意获取到该密钥,然后对我们的业务请求参数进行解密,我们需要将AES密钥进行非对称加密后再进行传输

代码实现

AESUtils :AES工具类


import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
 
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
 
/**
 * @author 
 * @program 
 * @description
 * @create 2022/10/17 10:57
 **/
public class AESUtils {
 
    /**
     * 编码格式
     */
    public static final String CHARSET = "UTF-8";
 
    /**
     * 加密算法
     */
    public static final String AES_ALGORITHM = "AES";
 
    /**
     * 生成密钥
     * @return
     */
    public static String generateKey() {
        try {
            //1.构造密钥生成器,指定为AES算法,不区分大小写
            KeyGenerator keygen = KeyGenerator.getInstance(AES_ALGORITHM);
            //2.生成一个128位的随机源
            keygen.init(128, new SecureRandom());
            //3.产生原始对称密钥
            SecretKey secretKey = keygen.generateKey();
            //4.获得原始对称密钥的字节数组
            byte[] byteKey = secretKey.getEncoded();
            //5.返回密钥
            return Hex.encodeHexString(byteKey);
        }catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
 
        //如果有错就返加nulll
        return null;
    }
 
    /**
     * 加密
     * @param thisKey 密钥
     * @param data 数据
     * @return 加密后的数据
     */
    public static String encode(String thisKey, String data) {
        try {
            //1.转换KEY
            Key key = new SecretKeySpec(Hex.decodeHex(thisKey), AES_ALGORITHM);
            //2.根据指定算法AES自成密码器
            Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
            //3.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
            cipher.init(Cipher.ENCRYPT_MODE, key);
            //4.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
            byte[] byteEncode = data.getBytes(CHARSET);
            //5.根据密码器的初始化方式--加密:将数据加密
            byte[] result = cipher.doFinal(byteEncode);
            //6.将字符串返回
            return Hex.encodeHexString(result);
        } catch (DecoderException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        //如果有错就返加nulll
        return null;
    }
 
    /**
     * 解密
     * @param thisKey 密钥
     * @param data 加密的数据
     * @return 解密后的数据
     */
    public static String decode(String thisKey, String data) {
        try {
            //1.转换KEY
            Key key = new SecretKeySpec(Hex.decodeHex(thisKey), AES_ALGORITHM);
            //2.根据指定算法AES自成密码器
            Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
            //3.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
            cipher.init(Cipher.DECRYPT_MODE, key);
            //4.将加密并编码后的内容解码成字节数组
            byte[] byteContent = Hex.decodeHex(data);
            //5.解密
            byte[] byteDecode = cipher.doFinal(byteContent);
            //6.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
            return new String(byteDecode, CHARSET);
        } catch (DecoderException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e) {
            e.printStackTrace();
        }
 
        //如果有错就返加nulll
        return null;
    }
 
    public static void main(String[] args) {
        String key = generateKey();
        System.out.println("生成的密钥为:" + key);
//        String pubKey = "6aa7066f738828f333b1bb84b62606c6";
//        String priKey = "6aa7066f738828f333b1bb84b62606c6";
        String data = "使用AES对称加密,请输入加密的规则使用AES对称加密AAAAAABBBBB";
        String encodeData = encode(key, data);
        System.out.println("加密后的数据为:" + encodeData);
        String decodeData = decode(key, encodeData);
        System.out.println("解密后的数据为:" + decodeData);
    }
}

RSAUtils :RSA工具类


import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;

import javax.crypto.Cipher;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Method;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

/**
 * @author 
 * @program 
 * @description
 * @create 2022/10/17 10:57
 **/
public class RSAUtils {

    /**
     * 编码格式
     */
    public static final String CHARSET = "UTF-8";

    /**
     * 加密算法
     */
    public static final String RSA_ALGORITHM = "RSA";

    /**
     * 定义签名算法
     */
    private final static String KEY_RSA_SIGNATURE = "MD5withRSA";


    /**
     * 得到公钥
     *
     * @param publicKey 密钥字符串(经过base64编码)
     * @throws Exception
     */
    public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        //通过X509编码的Key指令获得公钥对象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
        return (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
    }

    /**
     * 得到私钥
     *
     * @param privateKey 密钥字符串(经过base64编码)
     * @throws Exception
     */
    public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        //通过PKCS#8编码的Key指令获得私钥对象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
        RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
        return key;
    }

    /**
     * 公钥加密
     *
     * @param data
     * @param publicKey
     * @return
     */
    public static String publicEncrypt(String data, RSAPublicKey publicKey) {
        try {
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));
        } catch (Exception e) {
            throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
        }
    }

    /**
     * 私钥解密
     *
     * @param data
     * @param privateKey
     * @return
     */
    public static String privateDecrypt(String data, RSAPrivateKey privateKey) {
        try {
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET);
        } catch (Exception e) {
            throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
        }
    }

    /**
     * 分段加解密
     *
     * @param cipher
     * @param opmode
     * @param datas
     * @param keySize
     * @return
     */
    private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
        int maxBlock = 0;
        if (opmode == Cipher.DECRYPT_MODE) {
            maxBlock = keySize / 8;
        } else {
            maxBlock = keySize / 8 - 11;
        }
        ByteArrayOutputStream
                out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] buff;
        int i = 0;
        try {
            while (datas.length > offSet) {
                if (datas.length - offSet > maxBlock) {
                    buff = cipher.doFinal(datas, offSet, maxBlock);
                } else {
                    buff = cipher.doFinal(datas, offSet, datas.length - offSet);
                }
                out.write(buff, 0, buff.length);
                i++;
                offSet = i * maxBlock;
            }
        } catch (Exception e) {
            throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e);
        }
        byte[] resultDatas = out.toByteArray();
        IOUtils.closeQuietly(out);
        return resultDatas;
    }

    /**
     * 用私钥对信息生成数字签名
     *
     * @param data       加密数据
     * @param privateKey 私钥
     */
    public static String sign(byte[] data, String privateKey) {
        String str = "";
        try {
            // 解密由base64编码的私钥
            byte[] bytes = decryptBase64(privateKey);
            // 构造PKCS8EncodedKeySpec对象
            PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(bytes);
            // 指定的加密算法
            KeyFactory factory = KeyFactory.getInstance(RSA_ALGORITHM);
            // 取私钥对象
            PrivateKey key = factory.generatePrivate(pkcs);
            // 用私钥对信息生成数字签名
            Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
            signature.initSign(key);
            signature.update(data);
            str = encryptBase64(signature.sign());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str;
    }

    /**
     * 校验数字签名
     *
     * @param data      加密数据
     * @param publicKey 公钥
     * @param sign      数字签名
     * @return 校验成功返回true,失败返回false
     */
    public static boolean verify(byte[] data, String publicKey, String sign) {
        boolean flag = false;
        try {
            // 解密由base64编码的公钥
            byte[] bytes = decryptBase64(publicKey);
            // 构造X509EncodedKeySpec对象
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
            // 指定的加密算法
            KeyFactory factory = KeyFactory.getInstance(RSA_ALGORITHM);
            // 取公钥对象
            PublicKey key = factory.generatePublic(keySpec);
            // 用公钥验证数字签名
            Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
            signature.initVerify(key);
            signature.update(data);
            flag = signature.verify(decryptBase64(sign));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * BASE64 解密
     *
     * @param key 需要解密的字符串
     * @return 字节数组
     */
    public static byte[] decryptBase64(String key) {
        return Base64.decodeBase64(key);
    }

    /**
     * BASE64 加密
     *
     * @param key 需要加密的字节数组
     * @return 字符串
     */
    public static String encryptBase64(byte[] key) {
        return new String(Base64.encodeBase64(key));
    }

    /**
     * bean转map
     *
     * @param obj
     * @return
     */
    public static Map<String, Object> beanToMap(Object obj) {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                // 过滤class属性
                if (!"class".equals(key)) {
                    // 得到property对应的getter方法
                    Method getter = property.getReadMethod();
                    Object value = getter.invoke(obj);
                    if (value == null) {
                        continue;
                    }
                    map.put(key, value);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 按照红黑树(Red-Black tree)的 NavigableMap 实现
     * 按照字母大小排序
     *
     * @param map
     * @return
     */
    public static Map<String, Object> sort(Map<String, Object> map) {
        if (map == null) {
            return null;
        }
        Map<String, Object> result = new TreeMap<>((Comparator<String>) (o1, o2) -> {
            return o1.compareTo(o2);
        });
        result.putAll(map);
        return result;
    }

    /**
     * 组合参数
     *
     * @param map
     * @return 如:key1Value1Key2Value2....
     */
    public static String groupStringParam(Map<String, Object> map) {
        if (map == null) {
            return null;
        }
        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, Object> item : map.entrySet()) {
            if (item.getValue() != null) {
                sb.append(item.getKey());
                if (item.getValue() instanceof List) {
                    sb.append(JSON.toJSONString(item.getValue()));
                } else {
                    sb.append(item.getValue());
                }
            }
        }
        return sb.toString();
    }

    /**
     * 将Hex String转换为Byte数组
     *
     * @param hexString
     * @return
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    /**
     * @brief char to byte
     */
    public static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }


    public static void main(String[] args) throws Exception {
        String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFRIbGz6PJm3kboIzXr8Vw4Yv80xWwpNRNELVVTeXQXlB0kZ5-XfBdqDW3PkVM5ePxn1tNfiHxZvvgKr80Y5Un51-987lS8O2gh4juIOpIQ9LEHbEcoABtH2gGVmDGEdVtzfOXTSiDPW_0E6bAbD5Yzmw2Uf8e_bsiMH_sjIwiQIDAQAB";
        String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMIVEhsbPo8mbeRugjNevxXDhi_zTFbCk1E0QtVVN5dBeUHSRnn5d8F2oNbc-RUzl4_GfW01-IfFm--AqvzRjlSfnX73zuVLw7aCHiO4g6khD0sQdsRygAG0faAZWYMYR1W3N85dNKIM9b_QTpsBsPljObDZR_x79uyIwf-yMjCJAgMBAAECgYEAo8ZyE-umm9e67gOO3Vh7eRsYdggiCCiDdgfayfjyQzId57xQeodYVioLyaSIkCqMH-hIWUss4S2Qy8dRAqy3JBs6wrXIfWCMYMS1yRLJ1zbZvflCKgylTd3VY6iFfOeOviGTetVtr0iVesV0CrP_N9_iQFqMOCyJXAI8oGFGv90CQQDpv9W1eUdrxJ9wvf8nDFtKg-AdNQkJXlckyi2ZdSzp2q6o3_2O6SAIv1Rjal9SJkVnDnQFFx-a6JhoPER3LWnLAkEA1I6aHXCmSlhg1f3a-RjJyWmGVL05agOWx-HqfBv9WrsKz3khBLFtRu_MG52bazVOm8cZ3du422bEw0bQr8WUewJAewsSMd7Pa7kqvKwm3aUxgP3-QSGjyhyw_pq2eismI0uL2TVfQZUR2cjtYQ-jcZjXu7Ht_Kf5aQ-6-lOPLrTnFQJAMHEvfnYl79ukdiCcvxh_JIAANV_KrfaTbop2PkLCwuLN2-rnM4KcPQZ5pfGNcil7-NSveHiS8K3DOh3xgZ2t8QJAccgZKfAU7WV9nL1ZOMpqjIfl5KbwyChsY2oU7GWLinUEL5kjqgU1Y6LWIrzuPGGc2eL2iHXp2JCepKYMvwTFKw";

        System.out.println("公钥加密——私钥解密");
        String str = "code_cayden";
        System.out.println("\r明文:\r\n" + str);
        System.out.println("\r明文大小:\r\n" + str.getBytes().length);
        String encodedData = RSAUtils.publicEncrypt(str, RSAUtils.getPublicKey(publicKey));
        System.out.println("密文:\r\n" + encodedData);
        String decodedData = RSAUtils.privateDecrypt(encodedData, RSAUtils.getPrivateKey(privateKey));
        System.out.println("解密后文字: \r\n" + decodedData);
    }
}

RequestApiParam :接口参数对象


import lombok.Data;

import javax.validation.constraints.NotBlank;

/**
 * @author 
 * @program 
 * @description
 * @create 2022/10/17 10:57
 **/
@Data
public class RequestApiParam {

    /**
     * 接口id (可空)
     */
    private String serviceId;

    /**
     * 商户id (非空)
     */
    @NotBlank(message = "appid不能为空")
    private String appId;

    /**
     * 参数签名 (非空)
     */
    @NotBlank(message = "参数签名不能为空")
    private String sign;

    /**
     * 对称加密key (非空)
     */
    @NotBlank(message = "对称加密key不能为空")
    private String aseKey;

    /**
     * 时间戳,精确到毫秒 (非空)
     */
    private Long timestamp;

    /**
     * 请求的业务参数(AES加密后传入,可空)
     */
    @NotBlank(message = "请求的业务参数不能为空")
    private String body;

}

RSAKeyGenerator 生成RSA密钥对


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

import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author 
 * @program 
 * @description
 * @create 2022/10/17 10:57
 **/
public class RSAKeyGenerator {

    /**
     * 加密算法
     */
    public static final String RSA_ALGORITHM = "RSA";

    /**
     * 公钥key
     */
    private static final String PUBLIC_KEY = "publicKey";

    /**
     * 私钥KEY
     */
    private static final String PRIVATE_KEY = "privateKey";

    /**
     * APPID
     */
    private static final String APPID = "appId";

    /**
     * 生成公钥和私钥
     *
     * @param keySize
     * @return
     */
    public static Map<String, String> createKeys(int keySize) {
        //为RSA算法创建一个KeyPairGenerator对象
        KeyPairGenerator kpg;
        try {
            kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
        }

        //初始化KeyPairGenerator对象,密钥长度
        kpg.initialize(keySize);
        //生成密匙对
        KeyPair keyPair = kpg.generateKeyPair();
        //得到公钥
        Key publicKey = keyPair.getPublic();
        String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
        //得到私钥
        Key privateKey = keyPair.getPrivate();
        String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded());
        Map<String, String> keyPairMap = new HashMap<String, String>();
        keyPairMap.put(PUBLIC_KEY, publicKeyStr);
        keyPairMap.put(PRIVATE_KEY, privateKeyStr);
        keyPairMap.put(APPID, UUID.randomUUID().toString());

        return keyPairMap;
    }



    public static void main(String[] args) {
        Map<String, String> keyMap = RSAKeyGenerator.createKeys(1024);
        String publicKey = keyMap.get(PUBLIC_KEY);
        String privateKey = keyMap.get(PRIVATE_KEY);
        String appId = keyMap.get(APPID);
        System.out.println("公钥: " + publicKey);
        System.out.println("私钥: " + privateKey);
        System.out.println("appId: " + appId);

    }
}

测试类


import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 
 * @program 
 * @description
 * @create 2022/10/17 10:57
 **/
public class RequestTest {

    /**
     * 公钥key
     */
    private static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJAs7g-BKF15KUKxec-H2GC9Q22FMyho_AyByGqrM2uNWnBRQudE3wEWloi2PVGQ62vsTFUclNef2_xvdYWjF4TusUv_e9qwEypOyqQIeNUYmuUbJd_6iCUr2M9kqwj_KT2J106N1bkwRYSu0pCT_JoW7hTomRYXM3P235Bn8L-QIDAQAB";

    /**
     * 私钥KEY
     */
    private static final String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIkCzuD4EoXXkpQrF5z4fYYL1DbYUzKGj8DIHIaqsza41acFFC50TfARaWiLY9UZDra-xMVRyU15_b_G91haMXhO6xS_972rATKk7KpAh41Ria5Rsl3_qIJSvYz2SrCP8pPYnXTo3VuTBFhK7SkJP8mhbuFOiZFhczc_bfkGfwv5AgMBAAECgYAscZ_ANFh12C7xJ2VagvTc5btqKxQZ4LKC-6bdPEQ0LRMJQcmBJDMf-9Xwlr7EooM2Xn2f8F7XZgodCqKzo1ZGUH9ZXusQKcEXr6b6sfREfIuHIuMoeksMEfCyV-7yZG2k2aHtExfn7rz-LJO-uX28HWvhomKxOlyfbpBhM60eAQJBANri0-Z39bpFs73Dq8ZghqaoV-5T_mhGTkQuWs7VhL83AnF2OZOECW9cwcP20nV5w5_Tm2izSqVmX_6Hq5UEGsECQQCgPgjHblTMHyx6lPIu4Oyr0b84b34f0yDi37qneOZ2EX78yhEQ3dSLwh4ToBcNlZ6Zn8_rZX74SSxsjdIuXdc5AkAKRE1wJ_xMqmxN4Fm0Sl7GfmrxcNskBPgy1oHH5df-KBRjQgpdUvomURF9oZwpinaUjpZhiNddfrnN9IslyDWBAkBC98n5ds2vhPO0wxy3pL6kTAMrVcUTDcw3pKLALNG71DIK-XPKZbrXMagaMZSQ08-1ikl9qiw3HXWYZGjLgeJZAkEAp1U6zcjarlH2xy2NGbdqBelebufxl9MXi6swtSqRE8HewxPgiAuSzDNwjM4S0vNYtsdSB-Zhi8mDXyckitM2zQ";

    /**
     * appid
     */
    private static final String APP_ID = "445d748d-91fd-48a5-a1a5-1dbf14b63fb7";

    public static void main(String[] args) throws Exception {
        /*****调用方(请求方)*****/
        //业务参数
        Map<String, Object> businessParams = new HashMap<>();
        businessParams.put("name", "testName");
        businessParams.put("content", "testContent");

        RequestApiParam jsonRequest = new RequestApiParam();
        jsonRequest.setAppId(APP_ID);
        long currentTimeMillis = System.currentTimeMillis();
        jsonRequest.setTimestamp(currentTimeMillis);
        //使用AES密钥,并对密钥进行rsa公钥加密
        String aseKey = AESUtils.generateKey();
        String aseKeyStr = RSAUtils.publicEncrypt(aseKey, RSAUtils.getPublicKey(PUBLIC_KEY));
        jsonRequest.setAseKey(aseKeyStr);
        //请求的业务参数进行加密
        String body = "";
        try {
            body = AESUtils.encode(aseKey, JSONObject.toJSONString(businessParams));
        } catch (Exception e) {
            throw new RuntimeException("报文加密异常", e);
        }
        jsonRequest.setBody(body);
        //json转map
        Map<String, Object> paramMap = RSAUtils.beanToMap(jsonRequest);
        paramMap.remove("sign");
        //私钥签名
        String sign = RSAUtils.sign(RSAUtils.hexStringToBytes(APP_ID + currentTimeMillis), PRIVATE_KEY);
        jsonRequest.setSign(sign);
        System.out.println("请求参数:" + jsonRequest);

        /*****调用方*****/

        /*****接收方*****/
        //验签
        Map<String, Object> paramMap2 = RSAUtils.beanToMap(jsonRequest);
        paramMap2.remove("sign");
        //签名验证 通过appid以及时间戳验签
        boolean verify = RSAUtils.verify(RSAUtils.hexStringToBytes("" + paramMap2.get("appId") + paramMap2.get("timestamp")), PUBLIC_KEY, jsonRequest.getSign());
        if (!verify) {
            throw new RuntimeException("签名验证失败");
        }
        //私钥解密,获取aseKey
        String aseKey2 = RSAUtils.privateDecrypt(jsonRequest.getAseKey(), RSAUtils.getPrivateKey(PRIVATE_KEY));
        if (!StringUtils.isEmpty(jsonRequest.getBody())) {
            // 解密请求报文
            String requestBody = "";
            try {
                requestBody = AESUtils.decode(aseKey2, jsonRequest.getBody());
            } catch (Exception e) {
                throw new RuntimeException("请求参数解密异常");
            }
            System.out.println("业务参数解密结果:" + requestBody);
        }
        /*****接收方*****/
    }
}

在这里插入图片描述

(*****************************************************)(* *)(* Advanced Encryption Standard (AES) *)(* Interface Unit v1.0 *)(* *)(* Readme.txt 自述文档 2004.12.03 *)(* *)(*****************************************************)(* 介绍 *)AES 是一种使用安全码进行信息加密的标准。它支持 128 位、192 位和 256 位长度的密匙。加密算法的实现在 ElAES.pas 单元中。本人将其加密方法封装在 AES.pas 单元中,只需要调用两个标准函数就可以完成字符串的加密和解密。(* 文件列表 *)..Source AES 单元文件..Example 演示程序(* 适用平台 *)这份 Delphi 的执行基于 FIPS 草案标准,并且 AES 原作者已经通过了以下平台的测试: Delphi 4 Delphi 5 C++ Builder 5 Kylix 1本人又重新进行了补充测试,并顺利通过了以下平台: Delphi 6 Delphi 7特别说明: 在 Delphi 3 标准版中进行测试时,因为缺少 Longword 数据类型和 Math.pas 文件,并且不支持 overload 指示字,所以不能正常编译。(* 演示程序 *)这个示例程序演示了如何使用 AES 模块进行字符串的加密和解密过程。(* 使用方法 *)在程序中引用 AES 单元。调用 EncryptString 和 DecryptString 进行字符串的加密和解密。详细参阅 Example 文件夹中的例子。 (* 许可协议 *)您可以随意拷贝、使用和发部这个程序,但是必须保证程序的完整性,包括作者信息、版权信息和说明文档。请勿修改作者和版权信息。 这个程序基于 Mozilla Public License Version 1.1 许可,如果您使用了这个程序,那么就意味着您同意了许可协议中的所有内容。您可以在以下站点获取一个许可协议的副本。 http://www.mozilla.org/MPL/许可协议的发布基于 "AS IS" 基础,详细请阅读该许可协议。Alexander Ionov 是 AES 算法的最初作者,保留所有权利。(* 作者信息 *)ElAES 作者:EldoS, Alexander IonovAES Interface Unit 作者:杨泽晖 (Jorlen Young)您可以通过以下方式与我取得联系。WebSite: http://jorlen.51.net/ http://mycampus.03.com.cn/ http://mycampus.1155.net/ http://mycampus.ecoo.net/ http://mycampus.5500.org/Email: stanley_xfx@163.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值