接口数据使用RSA加密

原需求:
发起HTTP的POST请求的入参格式为接口参数及参数值组成的JSON字符串,
该JSON字符串需进行RSA加密,
接口再使用HttpServletRequest获取参数值后对数据进行RSA解密。

而密钥最高为1024位,这使得加密时的字符串不能超过117个字节,于是需要对加密前的JSON字符串进行按字节分割后放入数组,然后对数组中的每一项分别加密,最后将加密后的数组转成JSON字符串后作为请求体传入。
这时 HttpServletRequest可以先拿到加密后的JSON数组,然后对加密后的JSON数组的每一项分别解密,最后可将解密后的JSON数组的每一项拼接成接口参数及参数值组成的JSON字符串从而实现原需求。

下面是相关代码

RSA加密工具

package com.ieslab.msgpush.util;

import org.springframework.stereotype.Service;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * @description: RSA加密工具
 * @author: yiwenli
 * @create: 2021-04-29 09:52
 **/
public class RSAUtil {

    /**
     * 获取公钥私钥
     */
    public static void initKey() {
        try {
            Base64.Encoder encoder = Base64.getEncoder();
            // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            // 初始化密钥对生成器,密钥大小为96-1024位
            keyPairGen.initialize(1024, new SecureRandom());
            // 生成一个密钥对,保存在keyPair中
            KeyPair keyPair = keyPairGen.generateKeyPair();
            // 得到私钥
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            // 得到公钥
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

            privateKeyStr = new String(encoder.encode((privateKey.getEncoded())));
            publicKeyStr = new String(encoder.encode(publicKey.getEncoded()));
        } catch (NoSuchAlgorithmException e) {

            e.printStackTrace();
        }

    }

    /**
     * RSA公钥加密
     *
     * @param str       加密字符串
     * @param publicKey 公钥
     */
    public static String encrypt(String str, String publicKey) {
        try {
            Base64.Decoder decoder = Base64.getDecoder();
            Base64.Encoder encoder = Base64.getEncoder();
            //base64编码的公钥
            byte[] decoded = decoder.decode(publicKey);
            RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
            //RSA加密
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            String outStr = encoder.encodeToString(cipher.doFinal(str.getBytes("UTF-8")));
            return outStr;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * RSA私钥解密
     *
     * @param str        加密字符串
     * @param privateKey 私钥
     */
    public static String decrypt(String str, String privateKey) {
        try {
            Base64.Decoder decoder = Base64.getDecoder();
            //64位解码加密后的字符串
            byte[] inputByte = decoder.decode(str.getBytes("UTF-8"));
            //base64编码的私钥
            byte[] decoded = decoder.decode(privateKey);
            RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
            //RSA解密
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            String outStr = new String(cipher.doFinal(inputByte));
            return outStr;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

将加密前的JSON串进行字节分割

 /**
     * 字符串分解放入Arrays 因为AES加密时的字符串不能超过117个字节
     *
     * @param paramsJson 完整的参数json字符串
     */
    private List<String> getParamJsonArray(String paramsJson) {
        List<String> result = new ArrayList<>();
        try {
            byte[] paramJsonByteArray = URLEncoder.encode(paramsJson, "UTF-8").getBytes("UTF-8");
            while(paramJsonByteArray.length > 0) {
                if(paramJsonByteArray.length > 117) {
                    byte[] paramByteArrayAdd = Arrays.copyOfRange(paramJsonByteArray, 0, 117);
                    result.add(new String(paramByteArrayAdd));
                    paramJsonByteArray = Arrays.copyOfRange(paramJsonByteArray, 117, paramJsonByteArray.length);
                    continue;
                }
                result.add(new String(paramJsonByteArray));
                break;
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return result;
    }

发送HTTP POST请求

/**
     * 发送HTTP POST请求
     *
     * @param url  请求地址
     * @param data 请求参数
     */
    public static String httpPost(String url, String data) {
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
        httpPost.setEntity(new StringEntity(data, "UTF-8"));
        String result = null;
        try(CloseableHttpClient httpclient = HttpClients.createDefault();
            CloseableHttpResponse response = httpclient.execute(httpPost)) {
            HttpEntity entity = response.getEntity();
            result = EntityUtils.toString(entity, "UTF-8");
            EntityUtils.consume(entity);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

获取接口参数并解析后转换格式

/**
     * 获取接口参数并转换类型
     *
     * @param request
     */
    private JSONObject getParamObject(HttpServletRequest request) {
        StringBuilder requestValue = new StringBuilder();
        try(InputStream inputStream = request.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        ) {
            String line;//循环读取
            while ((line = reader.readLine()) != null) {
                requestValue.append(line);
            }
        } catch (Exception e){
            e.printStackTrace();
        }

        // 加密后的json数组
        List<String> paramJsonInCode = JSON.parseArray(requestValue.toString(), String.class);

        StringBuilder paramJson = new StringBuilder();

        // 对加密后的json数组的每一项分别解密
        for(String paramJsonOneInCode: paramJsonInCode) {
            paramJson.append(RSAUtil.decrypt(paramJsonOneInCode, RSAUtil.getPrivateKeyStr()));
        }

        try {
            String paramJsonDecode = URLDecoder.decode(paramJson.toString(), "UTF-8");
            return JSON.parseObject(paramJsonDecode);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值