Java的RSA分段加解密

Java的RSA分段解密

前言

加密的公私钥可以用工具类的generateRsaKey方法调用,也可以随便找个网站生成,本工具类生成的2048长度的秘钥,可以修改,如果修改了生成长度,记得把工具类前面的几个参数改了,加密分段长度计算方法:长度/8-11


一.调用

解密

Map<String, Object> resMap = new HashMap<>();
String encipher = RsaEncry.encipher(JSON.toJSONString(resMap));
System.out.println("加密后数据:" + encipher);

解密

String decipher = RsaEncry.decipher(data);
System.out.println("解密后数据:" + decipher);

二.工具类

package com.kaiwei.management.untils;

import org.apache.tomcat.util.codec.binary.Base64;

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.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * author: CD
 * Data: 2024-01-05 09:54:56 星期五
 * Description: rsa加解密
 */
public class RsaEncry {

    private static final int DEFAULT_RSA_KEY_SIZE = 2048;//生成密钥对长度
    private static final int ENSEGMENTSIZE = 245;//加密分段长度
    private static final int DESEGMENTSIZE = 256;//解密分段长度

    private static final String KEY_ALGORITHM = "RSA";

    static String publicRsaKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgsoD4g7tFPFVb/zjrhTIFqeZswoWhUTHxvOVn/ElCE35qdtdODKfABcVsFfLMmS/MdN1ZKN8MYFNThGgQODKdABNhy+FVNkdtR74m0u7i36nuCGHO+XhbzsimptaLD1HZC4AotVQGNd3mZx9D6rncfZeGxU0voZuQn9bN9UaYzOtNmNDH9uR+ZZA6asGxkPWjpHHJcF+GiSyP2kxQa5Mp1qkYqR5W+4KeLZZ1zOqs7Gzq1ubn0bexvHwR3wqqXebhppeY+tzL9zs8G6Jukwktvpw0ETd90hpPMIieW0pv2Tx6aVaCq3Nms08CL7X7xuUSf40qGYX2DB6J5dRksF3IwIDAQAB";
    static String privateRsaKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCCygPiDu0U8VVv/OOuFMgWp5mzChaFRMfG85Wf8SUITfmp2104Mp8AFxWwV8syZL8x03Vko3wxgU1OEaBA4Mp0AE2HL4VU2R21HvibS7uLfqe4IYc75eFvOyKam1osPUdkLgCi1VAY13eZnH0Pqudx9l4bFTS+hm5Cf1s31RpjM602Y0Mf25H5lkDpqwbGQ9aOkcclwX4aJLI/aTFBrkynWqRipHlb7gp4tlnXM6qzsbOrW5ufRt7G8fBHfCqpd5uGml5j63Mv3Ozwbom6TCS2+nDQRN33SGk8wiJ5bSm/ZPHppVoKrc2azTwIvtfvG5RJ/jSoZhfYMHonl1GSwXcjAgMBAAECggEAJDoiszYhM2DZoohw5GI7PhM0fqQ3srhngdMsyb243UED+6mYe52B7zt1tX/L9+xyDTIeXT7vgqLnL82wDuh1C4ad8ukVzHfLQ8UNZa6nhy8Q8+7Nj6jQNcgygJKxenmK0dPwNypQ4mCkbzcqaPGU5Dsyu9u23WNNHTw7nw53HazitbcMLS5xAOjMM+ZxDlHwFIAnCDQV7cmJVd43yRO7z5sBwT4lVP7OqkHWZvM+9mlcUi1ObP6imlN8ENKGtmucV3s2/I/Bc9hdofkvcU3L05OulhGf9YulPvNO4Hfp8emZsQf28Qf7oqCZofHdXYlkSnQqP6H18hmaiDAnHkEfOQKBgQD/EEF8oY8TFrIFbZWs/oeLWVHJP2me2qxbRSZktQn2kGoLDw5nvT1+7Ez+8fRhq3dGI+f0xZkEbkhPQAxyFHF/J7Ye8K6M83ELoHAyP2tndAsUD/P3gg3R+kArQ1wCpUwmXvWCzEIzpwSSlbP+IW2dYPDvA7cMSexaabSZmc8vNwKBgQCDRPLxZ1E+206pRpkjRyoaaF4ils3oKZOgRqGoBSdAACOPS9TQ8cr2ruJ8Jt7TkHsI1KranaUAl6uyUG+ZxOzM6q4sPvMzRMli1nni9Z8TsIRoY6Hjv3SDHPzT6omqZbS6+geg2eK+JPgygKFKUgiWsTM5xZ+4ycUxo/vqTEm1dQKBgQDCJ76hv11ou2rxxNQdpnbJNUmTdsjQmkZ/B2lNWZ3m6VE/b8uYXi4Uko2dt9I+EsatRqHH6i4reENkyC1xHWyzzSfN74n/U0RnBE7DgREh4+yW7fnZG0+n2eXEyPaeMPOBdeFPGmr+ZJGPf5NOzGVjWiqs1lgda5wVyscl8TYMCwKBgC0jHUKC2z343RB51Rh7VO/lqVDNeBn3ieqXvuhudTOdmJyiX5hFPBwcwIYeO4qV6Kh9sA4iHOWaQZC79dPzEdXYcHGIZ8neQj05MIopGT0E+lKGx9jvMVoQMqOPxyyPcljEtrDJmxz0y19aOZu7n3ZpkgqweJ5qyuKp12qWNtYtAoGBAJTUEaZP0H8cGAGlL9cJjM3jK671JtOoK4+SFss6KZYq2Qp40mfI2nmM2Y5Tmg72Tj+B8F0+b+9aLvGYN/DtmrX7UREGnMggmmmOw/Bwk9U5WiBMUWvc0HIqJ7+52AymZVqq9lJW7ZkmAClPBwoLCm5a9BxyB9iy1huSPjcBY4ku";

    //生成RSA 公私钥,可选长度为1025,2048位
    public static Map<String,String> generateRsaKey(int keySize) {
        Map<String,String> result = new HashMap<>(2);
        try {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);

            // 初始化密钥对生成器,密钥大小为1024 2048位
            keyPairGen.initialize(keySize, new SecureRandom());

            // 生成一个密钥对,保存在keyPair中
            KeyPair keyPair = keyPairGen.generateKeyPair();

            // 得到公钥字符串
            result.put("publicKey", new String(Base64.encodeBase64(keyPair.getPublic().getEncoded())));

            // 得到私钥字符串
            result.put("privateKey", new String(Base64.encodeBase64(keyPair.getPrivate().getEncoded())));

        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }
        return result;
    }

    //将公钥转换为base64格式
    public static PublicKey getPublicKey(String publicKeyBase64)
            throws InvalidKeySpecException, NoSuchAlgorithmException {

        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        X509EncodedKeySpec publicpkcs8KeySpec =
                new X509EncodedKeySpec(Base64.decodeBase64(publicKeyBase64));
        PublicKey publicKey = keyFactory.generatePublic(publicpkcs8KeySpec);
        return publicKey;
    }

    //将私钥转换为base64格式
    public static PrivateKey getPrivateKey(String privateKeyBase64)
            throws NoSuchAlgorithmException, InvalidKeySpecException{
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PKCS8EncodedKeySpec privatekcs8KeySpec =
                new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyBase64));
        PrivateKey privateKey = keyFactory.generatePrivate(privatekcs8KeySpec);
        return privateKey;
    }

    //分段加密
    public static String encipher(String ciphertext){
        try {
            int segmentSize = ENSEGMENTSIZE;
            PublicKey publicKey = getPublicKey(publicRsaKey);
            // 用公钥加密
            byte[] srcBytes = ciphertext.getBytes();

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

            if(segmentSize>0) {
                resultBytes = cipherDoFinal(cipher, srcBytes, segmentSize); //分段加密
            }
            else {
                resultBytes = cipher.doFinal(srcBytes);
            }
            String base64Str =  Base64.encodeBase64String(resultBytes);
            return base64Str;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    //分段解密
    public static String decipher(String contentBase64){
        try {
            int segmentSize = DESEGMENTSIZE;
            PrivateKey privateKey = getPrivateKey(privateRsaKey);
            // 用私钥解密
            byte[] srcBytes = Base64.decodeBase64(contentBase64);
            // Cipher负责完成加密或解密工作,基于RSA
            Cipher deCipher = Cipher.getInstance("RSA");
            // 根据公钥,对Cipher对象进行初始化
            deCipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] decBytes = null;//deCipher.doFinal(srcBytes);
            if(segmentSize>0) {
                decBytes = cipherDoFinal(deCipher, srcBytes, segmentSize); //分段加密
            }
            else {
                decBytes = deCipher.doFinal(srcBytes);
            }
            String decrytStr=new String(decBytes);
            return decrytStr;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    //分段大小
    private 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) {
                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;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值