RSA加密工具类

签名产生规则:使用字母排序后拼接待加密字符串。形如:key1=value1&key2=value2&key3=value3,使用公钥结合RSA加密算法进行加密,传输中对密文使用URL编码。

公私钥地址

//D:/workspaces/xxx/rsa/
@Value("${RSA.pubKeyFile}")
private String pubKeyFile;

//D:/workspaces/xxx/rsa/
@Value("${RSA.priKeyFile}")
private String priKeyFile;

生成公私钥文件

 public ObjectRestResponse<Object> generateKey(String platformCode) throws Exception {
        KeyPair keyPair = RSAPassWordUtils.generateKeyPair();
        // 获取 公钥 和 私钥
        PublicKey pubKey = keyPair.getPublic();
        PrivateKey priKey = keyPair.getPrivate();
        // 保存 公钥 和 私钥
        File file = new File(pubKeyFile+platformCode);
        if (!file.exists()){
            file.mkdirs();
        }
        RSAPassWordUtils.saveKeyForEncodedBase64(pubKey, new File(pubKeyFile+platformCode+"/pub.txt"));
        RSAPassWordUtils.saveKeyForEncodedBase64(priKey, new File(priKeyFile+platformCode+"/pri.txt"));
        System.out.println("公私钥文件路径:"+pubKeyFile+platformCode+"/pub.txt");
        return new ObjectRestResponse<>().data(true);
    }

私钥加密

public ObjectRestResponse<Object> priKeyEncrypt(@RequestBody ThirdPartyVo thirdPartyVo) throws Exception {
        Map<String, Object> map = BeanUtil.beanToMap(thirdPartyVo);
        String jsonObject = RSAPassWordUtils.sort(map,"&");
//        JSON parse = JSONUtil.parse(thirdPartyVo);
//        String jsonObject = parse.toString();
        log.info("加密对象=============="+jsonObject);
        File path = new File(priKeyFile + thirdPartyVo.getPlatformCode());
        if (!path.exists()){
            path.mkdirs();
        }
        File file = new File(priKeyFile + thirdPartyVo.getPlatformCode() + "/pri.txt");
        String base64 = IOUtils.readFile(file);
        String signPassword = RSAPassWordUtils.priKeyencrypt(jsonObject, base64);
        return new ObjectRestResponse<>().data(signPassword);
    }
package com.tomato.platform.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.json.JSONUtil;
import com.tomato.platform.model.vo.ThirdPartyVo;
import org.apache.commons.codec.binary.Base64;

import org.apache.commons.lang3.StringUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import java.io.*;
import java.lang.reflect.Field;
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.*;

public class RSAPassWordUtils {
    /**
     * 算法名称
     */
    private static final String ALGORITHM = "RSA";
    /** *//**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = 117;

    /** *//**
     * RSA最大解密密文大小
     */
    private static final int MAX_DECRYPT_BLOCK = 256;

    /**
     * 密钥长度
     */
    private static final int KEY_SIZE = 2048;

    /**
     * 随机生成密钥对(包含公钥和私钥)
     */
    public static KeyPair generateKeyPair() throws Exception {
        // 获取指定算法的密钥对生成器
        KeyPairGenerator gen = KeyPairGenerator.getInstance(ALGORITHM);

        // 初始化密钥对生成器(指定密钥长度, 使用默认的安全随机数源)
        gen.initialize(KEY_SIZE);

        // 随机生成一对密钥(包含公钥和私钥)
        return gen.generateKeyPair();
    }

    /**
     * 将 公钥/私钥 编码后以 Base64 的格式保存到指定文件
     */
    public static void saveKeyForEncodedBase64(Key key, File keyFile) throws IOException {
        // 获取密钥编码后的格式
        byte[] encBytes = key.getEncoded();

        // 转换为 Base64 文本
        String encBase64 = new BASE64Encoder().encode(encBytes);
        // 保存到文件
        IOUtils.writeFile(encBase64, keyFile);
    }

    /**
     * 根据公钥的 Base64 文本创建公钥对象
     */
    public static PublicKey getPublicKey(String pubKeyBase64) throws Exception {
        // 把 公钥的Base64文本 转换为已编码的 公钥bytes
        byte[] encPubKey = new BASE64Decoder().decodeBuffer(pubKeyBase64);

        // 创建 已编码的公钥规格
        X509EncodedKeySpec encPubKeySpec = new X509EncodedKeySpec(encPubKey);

        // 获取指定算法的密钥工厂, 根据 已编码的公钥规格, 生成公钥对象
        return KeyFactory.getInstance(ALGORITHM).generatePublic(encPubKeySpec);
    }

    /**
     * 根据私钥的 Base64 文本创建私钥对象
     */
    public static PrivateKey getPrivateKey(String priKeyBase64) throws Exception {
        // 把 私钥的Base64文本 转换为已编码的 私钥bytes
        byte[] encPriKey = new BASE64Decoder().decodeBuffer(priKeyBase64);

        // 创建 已编码的私钥规格
        PKCS8EncodedKeySpec encPriKeySpec = new PKCS8EncodedKeySpec(encPriKey);

        // 获取指定算法的密钥工厂, 根据 已编码的私钥规格, 生成私钥对象
        return KeyFactory.getInstance(ALGORITHM).generatePrivate(encPriKeySpec);
    }

    /**
     * 公钥加密数据
     */
    public static byte[] encrypt(byte[] plainData, PublicKey pubKey) throws Exception {
        // 获取指定算法的密码器
        Cipher cipher = Cipher.getInstance(ALGORITHM);

        // 初始化密码器(公钥加密模型)
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);

        // 加密数据, 返回加密后的密文
        return cipher.doFinal(plainData);
    }

    /**
     * 私钥解密数据
     */
    public static byte[] decrypt(byte[] cipherData, PrivateKey priKey) throws Exception {
        // 获取指定算法的密码器
        Cipher cipher = Cipher.getInstance(ALGORITHM);

        // 初始化密码器(私钥解密模型)
        cipher.init(Cipher.DECRYPT_MODE, priKey);

        // 解密数据, 返回解密后的明文
        return cipher.doFinal(cipherData);
    }

    public static String priKeyencrypt( String str, String privateKey ) throws Exception{

        //base64编码的公钥

        byte[] decoded = Base64.decodeBase64(privateKey);

        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));

        //RSA加密
        Cipher cipher = Cipher.getInstance("RSA");

        cipher.init(Cipher.ENCRYPT_MODE, priKey);

        String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));

        return outStr;

    }
    public static String pubKeydecrypt(String str, String publicKey) throws Exception{

        //64位解码加密后的字符串

        byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));

        //base64编码的公钥

        byte[] decoded = Base64.decodeBase64(publicKey);

        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));

            //RSA解密

        Cipher cipher = Cipher.getInstance("RSA");

        cipher.init(Cipher.DECRYPT_MODE, pubKey);

        String outStr = new String(cipher.doFinal(inputByte));

        return outStr;

    }
    /**
     * 使用公钥解密
     * @param data 已加密数据
     * @see decByPriKey
     */
    public static String decryptByPublicKey(String data,String pubKey) {
        // 加密
        String str = "";
        try {
            byte[] pubByte = Base64.decodeBase64(pubKey.getBytes("UTF-8"));
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubByte);
            KeyFactory fac = KeyFactory.getInstance("RSA");
            RSAPublicKey rsaPubKey = (RSAPublicKey) fac.generatePublic(keySpec);
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, rsaPubKey);
            byte[] dataBytes = Base64.decodeBase64(data);
            int inputLen = dataBytes.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offset = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段解密
            while (inputLen - offset > 0) {
                if (inputLen - offset > MAX_DECRYPT_BLOCK) {
                    cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
                }
                out.write(cache, 0, cache.length);
                i++;
                offset = i * MAX_DECRYPT_BLOCK;
            }
            byte[] decryptedData = out.toByteArray();
            out.close();
            str = new String(decryptedData);
        } catch (Exception e) {
            e.printStackTrace();

        }
        // 解密后的内容
        return str;
    }

    public static Boolean auth(ThirdPartyVo thirdPartyVo,Map<String, String> map) throws Exception {
        ThirdPartyVo partyVo = BeanUtil.mapToBean(map, ThirdPartyVo.class, false, new CopyOptions());
        if (thirdPartyVo.getPlatformCode().equals(partyVo.getPlatformCode()) && thirdPartyVo.getPhone().equals(partyVo.getPhone())
        &&thirdPartyVo.getTimestamp().equals(partyVo.getTimestamp())
        ){
            if (thirdPartyVo.getAddress() != null && thirdPartyVo.getBusiWebsite() != null){
                if (!thirdPartyVo.getAddress().equals(partyVo.getAddress()) || !thirdPartyVo.getBusiWebsite().equals(partyVo.getBusiWebsite())){
                    throw new Exception("地址或网址错误!");
                }
            }
        }else {
            throw new Exception("请检查平台商户编码、时间戳、电话号码是否正确!!");
        }
        return true;
    }
/**
**使用字母排序后拼接待加密字符串。形如:key1=value1&key2=value2&key3=value3,
** separator参数表示分隔符"&"
**/
    public static String sort(Map<String, Object> params, String separator) throws Exception {
        if (null == params || params.isEmpty()) {
            throw new Exception("接口参数不能为空。");
        }

        List<Map.Entry<String, Object>> entrys = new ArrayList<>(params.entrySet());
        Collections.sort(entrys, Comparator.comparing(Map.Entry::getKey));

        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Object> entry : entrys) {
            String key = entry.getKey();
            if (key.equalsIgnoreCase("sign")) {
                continue;
            }
            if (entry.getValue() != null){
                String value = entry.getValue().toString();
                sb.append(key).append("=").append(value).append(separator);
            }
        }
        return sb.substring(0, sb.length() - separator.length());
    }
/**
**将key1=value1&key2=value2&key3=value3转换为MAP
**/
    public static Map<String, String> getMap(String params) {
        HashMap<String, String> map = new HashMap<>();

        int start = 0, len = params.length();

        while (start < len) {
            int i = params.indexOf('&', start);

            if (i == -1) {
                i = params.length(); // 此时处理最后的键值对
            }

            String keyValue = params.substring(start, i);

            int j = keyValue.indexOf('=');
            String key = keyValue.substring(0, j);
            String value = keyValue.substring(j + 1, keyValue.length());

            map.put(key, value);

            if (i == params.length()) {
                break;
            }

            start = i + 1; // index+1 为下一个键值对的起始位置
        }

        return map;
    }

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值