分享一下java对数据传输的加密加签

以前公司的项目主要是一些内网用的系统,最近换了一家公司,都是面向网络用户的。有与第三方平台合作的情况,为了保证请求数据的安全,对方向我们传输数据都会对数据进行加密以及添加数字签名。我们拿到对方加密的数据后,再进行验签解密。请求对方的接口也是一样的。下面就说以一下这个过程吧

参数加密解密:
加密:我方AES密钥对data参数进行对称加密,然后在通过我方RSA私钥将data密文与其他参数拼接成字符串进行非对称加密得到sign签名。
解密:先使用对方公钥进行验签,再使用对方AES密钥进行参数解密。

下面是个参数加密解密的demo



import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.apache.commons.lang3.StringUtils;
import sun.misc.BASE64Decoder;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

/**
 * @Description 加签、加密、验签、解密 demo
 * @Date 2021/5/7
 * @Version V1.0
 * @Author Zhoushuang
 */
public class EncryptDemo {

    private static String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCE8f+k5wXFHJK7Lxeik8yVM6ky93J7QoFD9db9zLcgJhalSYgvAafqRfqPmpjnaD/1co4gmNy+oS2ZEvHIfgSuFyrmjSklQy3k+oHYVTyeQ5ypnmoMZrln70Hi4x77+zTqXRmrQBfeLpuyvl/bt98OGQaKKLiBpLl6cNUnbrSPqQIDAQAB";
    private static String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAITx/6TnBcUckrsvF6KTzJUzqTL3cntCgUP11v3MtyAmFqVJiC8Bp+pF+o+amOdoP/VyjiCY3L6hLZkS8ch+BK4XKuaNKSVDLeT6gdhVPJ5DnKmeagxmuWfvQeLjHvv7NOpdGatAF94um7K+X9u33w4ZBooouIGkuXpw1SdutI+pAgMBAAECgYBi3ROfLa28x2LWkE6jOAYLbj+FBz67Ktm2EDuwwWvtHGX6xJPhYPnd3exWnkDW1U+611WaKBMAMBwYmV30GsKfGYaVhZRv1nSe+midcl7PhM+a3fItVn+mU1Idr4n7GyeYciCbiuYjRBH+GfIQmz0W1QHewE0bVUjAWX1elFBwAQJBAOqN9/4pSrLmnHz144f7PCP7VsMF/B7c77WKhs4kI9dUdrIX+fRp9qcBzSdssV/3dghMxcBGO0zu3b5MdKTE0fkCQQCRGb5AyRy7yke9NnELzeVh3KkvB+QyHAYpSH/gU+Auc8NgE0UnXPqjZG7bG/SnK75LbVnT9hRoaSy8963SQxcxAkEAw9zFR4GnlPipmFekJnsO32UUMEqhHAyWRtxkcWMQYtFvRIxs90I863y/mbpT67Uy5P9m6oY7IqUcmboydRy90QJAPDuIe5JAiD/W+deQo8rLro0P+gL3mkmB0T9UPgXzaLULZGV7bnStYog9cF0xePeyndL91/wtyo3mUWcrU74f8QJARDrh8E1on4UhWF9dC07GrbT9Ldo5NYsyXXznboUUNk5xbi4Lp0Rhp6ap2FW25oYFAe0zrcfN298gqTV+S3Uzbw==";
    private static String AES_KEY = "5E769625BC89A081B0C8FFD8E5F6C0E6";

    public static void main(String[] args) {
        //设置基础参数
        Integer pid_1 = 300055;
        String channelId_1 = "BRC";
//        JSONObject data_1 = JSONObject.parseObject("{\"applyId\":2100014767,\"loanAmount\":\"7000\",\"loanPeriod\":\"12\"}");
//        JSONObject data_1 = JSONObject.parseObject("{\"loanId\":2100014767}");
        JSONObject data_1 = JSONObject.parseObject("{\"loanId\":2100014767,\"repayType\":\"2\",\"periods\":\"1,2,3,4,5,6,7,8,9,10,11,12\"}");

        Long timestamp_1 = System.currentTimeMillis();
        //aes加密
        String dataAES_1 = encryptAES(AES_KEY, data_1.toString());
        //设置签名参数
        Map<String, String> signParam_1 = new HashMap<>();
        signParam_1.put("channelId", channelId_1);
        signParam_1.put("data", dataAES_1);
        signParam_1.put("pid", pid_1.toString());
        signParam_1.put("timestamp", timestamp_1.toString());
        //生成签名
        String sign = Encrypt.signSHA1(signParam_1, PRIVATE_KEY);
        JSONObject requestParam = new JSONObject();
        requestParam.put("channelId", channelId_1);
        requestParam.put("pid", pid_1);
        requestParam.put("data", dataAES_1);
        requestParam.put("sign", sign);
        requestParam.put("timestamp", timestamp_1);
        //最终的请求参数
        System.out.println(requestParam.toJSONString());

        //解密参数
        Integer pid_2 = requestParam.getInteger("pid");
        String channelId_2 = requestParam.getString("channelId");
        String dataAES_2 = requestParam.getString("data");
        Long timestamp_2 = requestParam.getLong("timestamp");
        //检查签名
        Map<String, String> signParam_2 = new HashMap<>();
        signParam_2.put("pid", pid_2.toString());
        signParam_2.put("channelId", channelId_2.toString());
        signParam_2.put("timestamp", timestamp_2.toString());
        signParam_2.put("data", dataAES_2);
        boolean flag = Encrypt.checkSignSHA1(signParam_2, requestParam.getString("sign"), PUBLIC_KEY);
        if (!flag) {
            System.out.println("签名错误");
            return;
        }
        System.out.println("签名正确");
        //aes解密
        JSONObject data_2 = JSONObject.parseObject(decryptAES(AES_KEY, dataAES_2));
        System.out.println("解密后的data:" + data_2.toString());

    }


    /**
     * ras加签、验签
     */
    static class Encrypt {
        /**
         * 加签
         *
         * @param signParams
         * @param privateKey
         * @return
         */
        public static String signSHA1(Map<String, String> signParams, String privateKey) {
            return initSign("SHA1withRSA", signParams, privateKey);
        }

        /**
         * 验签
         *
         * @param signParams
         * @param sign
         * @param publicKey
         * @return
         */
        public static boolean checkSignSHA1(Map<String, String> signParams, String sign, String publicKey) {
            return rsa256CheckContent("SHA1withRSA", signParams, sign, publicKey);
        }

        private static boolean rsa256CheckContent(String signType, Map<String, String> signParams, String sign, String publicKey) {
            try {
                String content = getSignContent(signParams);
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                byte[] encodedKey = Base64.decode(publicKey);
                PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
                Signature signature = Signature.getInstance(signType);
                signature.initVerify(pubKey);
                signature.update(content.getBytes("utf-8"));
                boolean bverify = signature.verify(Base64.decode(sign));
                return bverify;
            } catch (Exception var10) {
                var10.printStackTrace();
                return false;
            }
        }

        private static String initSign(String signType, Map<String, String> signParams, String privateKey) {
            try {
                String content = getSignContent(signParams);
                PrivateKey priKey = getPrivateKeyFromPKCS8(privateKey);
                Signature signature = Signature.getInstance(signType);
                signature.initSign(priKey);
                signature.update(content.getBytes("utf-8"));
                byte[] signed = signature.sign();
                return new String(Base64.encode(signed));
            } catch (Exception var7) {
                System.out.println("生成签名异常:" + var7.getMessage());
                var7.printStackTrace();
                return null;
            }
        }

        public static String getSignContent(Map<String, String> sortedParams) {
            StringBuffer content = new StringBuffer();
            List<String> keys = new ArrayList(sortedParams.keySet());
            //对key进行排序
            Collections.sort(keys);
            int index = 0;
            for (int i = 0; i < keys.size(); ++i) {
                String key = keys.get(i);
                String value = sortedParams.get(key);
                if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank((value))) {
                    content.append((index == 0 ? "" : "&") + key + "=" + value);
                    ++index;
                }
            }

            return content.toString();
        }

        private static PrivateKey getPrivateKeyFromPKCS8(String priKey) {
            PrivateKey privateKey = null;
            if (StringUtils.isBlank(priKey)) {
                return privateKey;
            } else {
                try {
                    PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec((new BASE64Decoder()).decodeBuffer(priKey));
                    KeyFactory keyf = KeyFactory.getInstance("RSA");
                    privateKey = keyf.generatePrivate(priPKCS8);
                } catch (Exception var4) {
                    System.out.println("私钥解析错误:" + var4.getMessage());
                }

                return privateKey;
            }
        }
    }

    /**
     * aes加密
     *
     * @param base64Key
     * @param text
     * @return
     */
    public static String encryptAES(String base64Key, String text) {
        try {
            byte[] key = parseHexStr2Byte(base64Key);
            SecretKeySpec sKeySpec = new SecretKeySpec(key, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(1, sKeySpec);
            byte[] encryptBytes = cipher.doFinal(text.getBytes("utf-8"));
            return parseByte2HexStr(encryptBytes);
        } catch (Exception var6) {
            System.out.println("AES加密错误:" + var6.getMessage());
            return null;
        }
    }

    /**
     * aes解密
     *
     * @param base64Key
     * @param text
     * @return
     */
    public static String decryptAES(String base64Key, String text) {
        try {
            byte[] key = parseHexStr2Byte(base64Key);
            SecretKeySpec sKeySpec = new SecretKeySpec(key, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(2, sKeySpec);
            byte[] decryptBytes = cipher.doFinal(parseHexStr2Byte(text));
            return new String(decryptBytes, "UTF-8");
        } catch (Exception var6) {
            System.out.println("AES解密错误:" + var6.getMessage());
            return null;
        }
    }

    private static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1) {
            return null;
        } else {
            byte[] result = new byte[hexStr.length() / 2];

            for (int i = 0; i < hexStr.length() / 2; ++i) {
                int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
                int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
                result[i] = (byte) (high * 16 + low);
            }

            return result;
        }
    }

    public static String parseByte2HexStr(byte[] buf) {
        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < buf.length; ++i) {
            String hex = Integer.toHexString(buf[i] & 255);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }

            sb.append(hex.toUpperCase());
        }

        return sb.toString();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值