java RSA解决多内容加密解密(分段)

package com.qytb.utils;

import org.apache.commons.codec.binary.Base64;
import org.springframework.util.Base64Utils;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
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;


import static com.qytb.utils.IDRSAUtils.getPrivateKey;
import static com.qytb.utils.IDRSAUtils.getPublicKey;

public class RSAUtil {
    /**
     * RSA密钥长度必须是64的倍数,在512~65536之间。默认是1024
     */
    public static final int KEY_SIZE = 1024;
    private static Map<Integer, String> keyMap = new HashMap<Integer, String>();  //用于封装随机产生的公钥与私钥

    public static void main(String[] args) throws Exception {
//        //生成公钥和私钥
//        genKeyPair();
//        //加密字符串
//        String message = "df723820";
//        System.out.println("随机生成的公钥为:" + keyMap.get(0));
//        System.out.println("随机生成的私钥为:" + keyMap.get(1));
//        String messageEn = encrypt(message, keyMap.get(0));
//        System.out.println(message + "\t加密后的字符串为:" + messageEn);
//        String messageDe = decrypt(messageEn, keyMap.get(1));
//        System.out.println("还原后的字符串为:" + messageDe);

        HashMap<Object, Object> map = new HashMap<>();
        map.put("aa","dfasddfd");
        String publicKey = readConfig.getConfig("publicKey");
        String encrypt = encrypt(map.toString(), publicKey);
        System.out.println("加密内容========================="+encrypt);
    }

    /**
     * 随机生成密钥对
     *
     * @throws NoSuchAlgorithmException
     */
    public static void genKeyPair() throws NoSuchAlgorithmException {
        // 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();  // 得到公钥
        String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
        // 得到私钥字符串
        String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
        // 将公钥和私钥保存到Map
        keyMap.put(0, publicKeyString);  //0表示公钥
        keyMap.put(1, privateKeyString);  //1表示私钥
    }

    /**
     * RSA公钥加密
     *
     * @param str       加密字符串
     * @param publicKey 公钥
     * @return 密文
     * @throws Exception 加密过程中的异常信息
     */
    public static String encrypt(String str, String publicKey) throws Exception {
        //base64编码的公钥
        byte[] decoded = Base64.decodeBase64(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
        return encipher(str,pubKey , KEY_SIZE / 8 - 11);

    }

    public static String encryptone( String str, String publicKey ) throws Exception{
        //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.ENCRYPT_MODE, pubKey);
        String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
        return outStr;
    }


    /**
     * 分段加密
     *
     * @param ciphertext  密文
     * @param key         加密秘钥
     * @param segmentSize 分段大小,<=0 不分段
     * @return
     */
    public static String encipher(String ciphertext, java.security.Key key, int segmentSize) {
        try {
            // 用公钥加密
            byte[] srcBytes = ciphertext.getBytes("UTF-8");

            // Cipher负责完成加密或解密工作,基于RSA
            Cipher cipher = Cipher.getInstance("RSA");
            // 根据公钥,对Cipher对象进行初始化
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] resultBytes = null;

            if (segmentSize > 0) {
                resultBytes = cipherDoFinal(cipher, srcBytes, segmentSize);
            }
            else{
                resultBytes = cipher.doFinal(srcBytes);}


            //String decrytStr = new String(resultBytes);
            //String decrytStr = new String(resultBytes,"UTF-8");
            String decrytStr = Base64Utils.encodeToString(resultBytes);
            return decrytStr;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }



    /**
     * 使用私钥解密
     *
     * @param contentBase64    待解密内容,base64 编码
     * @param privateKeyBase64 私钥 base64 编码
     * @return
     * @segmentSize 分段大小
     */
    public static String decrypt (String contentBase64, String privateKeyBase64){
        return decipher(contentBase64, privateKeyBase64, KEY_SIZE / 8);
    }
    /**
     * 使用私钥解密(分段解密)
     *
     * @param contentBase64    待加密内容,base64 编码
     * @param privateKeyBase64 私钥 base64 编码
     * @return
     * @segmentSize 分段大小
     */
    public static String decipher (String contentBase64, String privateKeyBase64,int segmentSize){
        try {
            PrivateKey privateKey = getPrivateKey(privateKeyBase64);
            return decipher(contentBase64, privateKey, segmentSize);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
        /**
         * 分段解密
         *
         * @param contentBase64 密文
         * @param key           解密秘钥
         * @param segmentSize   分段大小(小于等于0不分段)
         * @return
         */
        public static String decipher (String contentBase64, java.security.Key key,int segmentSize){
            try {
                // 用私钥解密
                byte[] srcBytes = Base64Utils.decodeFromString(contentBase64);
                int length = srcBytes.length;
                // Cipher负责完成加密或解密工作,基于RSA
                Cipher deCipher = Cipher.getInstance("RSA");
                // 根据公钥,对Cipher对象进行初始化
                deCipher.init(Cipher.DECRYPT_MODE, key);
                byte[] decBytes = null;//deCipher.doFinal(srcBytes);
                if (segmentSize > 0) {
                    decBytes = cipherDoFinal(deCipher, srcBytes, segmentSize); //分段
                }
                else{
                    decBytes = deCipher.doFinal(srcBytes);
                }
                String decrytStr = new String(decBytes,"UTF-8");

                return decrytStr;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }

        public static byte[] cipherDoFinal (Cipher cipher,byte[] srcBytes, int segmentSize)
            throws IllegalBlockSizeException, BadPaddingException, IOException {
            if (segmentSize <= 0) {
                throw new RuntimeException("分段大小必须大于0");
            }
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int inputLen = srcBytes.length;
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段解密
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > segmentSize) {
                    int length = srcBytes.length;

                    cache = cipher.doFinal(srcBytes, offSet, segmentSize);
                } else {
                    cache = cipher.doFinal(srcBytes, offSet, inputLen - offSet);

                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * segmentSize;
            }
            byte[] data = out.toByteArray();
            out.close();
            return data;
        }


    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值