吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1620|回复: 4
收起左侧

[Java 原创] RSA加解密工具类(支持分段加解密)

  [复制链接]
sure975 发表于 2023-3-16 10:51
本帖最后由 sure975 于 2023-3-16 11:00 编辑

刚注册论坛,本人干java开发的,四年工作经验,给大家分享一下项目里面用到的RSA加解密工具类:
这个工具类的好处就是因为当需要加密的字符串长度较长的时候可以通过分段进行加密

[Java] 纯文本查看 复制代码
import kafka.log.Log;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

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.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: RSA加解密工具类
 * @fileName: RSAUtils.java
 * @author: Sure
 * @createAt: 2022/3/7 14:20
 * @updateBy: Sure
 * @remark: 
 */
@Slf4j
public class RsaUtils {

    /**
     * 加解密算法关键字
     */
    public static final String KEY_ALGORITHM = "RSA";

    /**
     * 公钥关键字
     */
    private static final String PUBLIC_KEY = "RSAPublicKey";

    /**
     * 私钥关键字
     */
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    /**
     * 默认编码
     */
    public static final String CHARSET = "UTF-8";

    /**
     * 最大加密字节数,超出最大字节数需要分组加密
     */
    private static int MAX_ENCRYPT_BLOCK = 117;

    /**
     * 最大解密字节数,超出最大字节数需要分组解密
     */
    private static int MAX_DECRYPT_BLOCK = 256;

    /**
     * 解密
     *
     * @param str        加密的base64串
     * @param privateKey base64私钥串
     * @return 解密后字符
     */
    public static String decrypt(String str, String privateKey) throws Exception {
        //64位解码加密后的字符串
        byte[] inputByte = Base64.decodeBase64(str.getBytes(CHARSET));
        //base64编码的私钥
        byte[] keyBytes = Base64.decodeBase64(privateKey.getBytes(CHARSET));
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
        //RSA解密
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        return new String(cipher.doFinal(inputByte), CHARSET);
    }

    /**
     * 加密
     *
     * @param data      需要加密的数据
     * @param publicKey base64公钥串
     * @return 加密后的base64字符串
     */
    public static String encrypt(String data, String publicKey) throws Exception {
        // 取得公钥
        Key key = KeyFactory.getInstance(KEY_ALGORITHM).generatePublic(new X509EncodedKeySpec(Base64.decodeBase64(publicKey.getBytes(CHARSET))));
        // 对数据加密
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return new String(Base64.encodeBase64(cipher.doFinal(data.getBytes(CHARSET))), CHARSET);
    }

    /**
     * 获取base64私钥
     *
     * @param keyMap 秘钥
     * @return 私钥
     */
    public static String getPrivateKeyStr(Map<String, Object> keyMap) {
        Key key = (Key) keyMap.get(PRIVATE_KEY);
        return Base64.encodeBase64String(key.getEncoded());
    }

    /**
     * 取得base64公钥
     *
     * @param keyMap 秘钥
     * @return base64公钥
     */
    public static String getPublicKeyStr(Map<String, Object> keyMap) {
        Key key = (Key) keyMap.get(PUBLIC_KEY);
        return Base64.encodeBase64String(key.getEncoded());
    }

    /**
     * 初始化秘钥
     *
     * @return 秘钥
     * @throws NoSuchAlgorithmException
     */
    public static Map<String, Object> initKey() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        keyPairGen.initialize(2048);
        KeyPair keyPair = keyPairGen.generateKeyPair();
        //公钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        //私钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        Map<String, Object> keyMap = new HashMap<>(5);

        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }


    /**
     * 分段解密
     * @param inputData 加密的base64字符串
     * @param privateKey base64的私钥
     * @return 解密后内容
     * @throws Exception
     */
    public static String decryptByShort(String inputData, String privateKey) throws Exception {
        //64位解码加密后的字符串
        byte[] inputBytes = Base64.decodeBase64(inputData.getBytes(CHARSET));
        //base64编码的私钥
        byte[] keyBytes = Base64.decodeBase64(privateKey.getBytes(CHARSET));
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
        //RSA解密
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        byte[] resultBytes = doFinalBySegment(inputBytes, cipher, MAX_DECRYPT_BLOCK);
        return new String(resultBytes, CHARSET);
    }

  /**
   * 分段公钥加密
  * @param inputData 需要加密的字符串
   * @param publicKey 公钥
  * @return: 加密后的base64编码
  */
    public static String encryptByShort(String inputData, String publicKey) throws Exception {
        // 取得公钥
        Key key = KeyFactory.getInstance(KEY_ALGORITHM).generatePublic(new X509EncodedKeySpec(Base64.decodeBase64(publicKey.getBytes(CHARSET))));
        // 对数据加密
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] resultBytes = doFinalBySegment(inputData.getBytes(CHARSET), cipher, MAX_ENCRYPT_BLOCK);
        return new String(Base64.encodeBase64(resultBytes), CHARSET);
    }

    /**
     * @Author: TheBigBlue
     * @Description: 分段加解密
     * @Date: 2019/9/24
     * @Return:
     **/
    private static byte[] doFinalBySegment(byte[] inputBytes, Cipher cipher, int maxLength) throws Exception {
        int inputLenth = inputBytes.length;
        log.info("数据超出最大字节数进行分段加解密:maxLength={}, inputLength={}", maxLength, inputLenth);
        // 标识
        int offSet = 0;
        byte[] cache;
        byte[] resultBytes = {};
        while (inputLenth - offSet > 0) {
            //超出最大字节数分组加密
            if (inputLenth - offSet > maxLength) {
                cache = cipher.doFinal(inputBytes, offSet, maxLength);
                offSet += maxLength;
            } else {
                //直接加密
                cache = cipher.doFinal(inputBytes, offSet, inputLenth - offSet);
                offSet = inputLenth;
            }
            resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
            System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
        }
        return resultBytes;
    }

}

免费评分

参与人数 1吾爱币 +7 热心值 +1 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| sure975 发表于 2023-3-16 10:53
注解啥的也都很详细,有问题的可以留言
Hmily 发表于 2023-3-16 10:54
 楼主| sure975 发表于 2023-3-16 10:57
Hmily 发表于 2023-3-16 10:54
代码建议用代码框处理一下,会好看很多。

我刚才编辑的时候还有的,我再研究研究
97okslj 发表于 2023-3-28 13:09
对于明文的密码帐号,怎么在代码里面加解密发布部署啊。
希望这样来实现明文传输密码信息而被泄露的风险
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 00:45

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表