RSA加密长度限制问题解决 BadPaddingException

Exception in thread "main" javax.crypto.BadPaddingException: Decryption error
    at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
    at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291)
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:356)
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
    at javax.crypto.Cipher.doFinal(Cipher.java:2223)
    at com.asymmetric.rsa.TestRSA.testDecrypt(TestRSA.java:115)
    at com.asymmetric.rsa.TestRSA.main(TestRSA.java:34)

RSA加密支持长度117,解密支持最大长度128【同事测试结果】
RSA可以用公钥加密,私钥解密,同时也可以用私钥加密,公钥解密;

直接贴工具类


import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * SecurityUtil简介
 *
 * @author zengdezheng3
 * @date 2020-02-20 19:29
 */
public class SecurityUtil {

    private final static Logger log = Logger.getLogger(SecurityUtil.class);
    private String secretKey;//加解密密钥
    private String charetSet = "utf-8";

    /**
     * 加密算法RSA
     */
    private static final String KEY_ALGORITHM = "RSA";
    /**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = 117;
    /**
     * RSA最大解密密文大小
     */
    private static final int MAX_DECRYPT_BLOCK = 128;
    /**
     * 常量0
     */
    private static final int ZERO = 0;

    public SecurityUtil(){

    }

    public SecurityUtil(String secretKey) {
        this.setSecretKey(secretKey);
    }

    public void setSecretKey(String secretKey) {
        this.secretKey = secretKey;
    }

    public void setCharetSet(String charetSet) {
        this.charetSet = charetSet;
    }

    /**
     * AES加密
     *
     * @param str
     * @return
     */
    public String encryptStrWithAes(String str) {
        String resStr = null;
        try {
            byte[] raw = secretKey.getBytes(charetSet);
            SecretKeySpec key = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//"算法/模式/补码方式"
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] byteContent = str.getBytes(charetSet);
            byte[] encrypted = cipher.doFinal(byteContent);
            BASE64Encoder encoder = new BASE64Encoder();
            resStr = encoder.encode(encrypted);
        } catch (Exception e) {
            log.error("AES加密失败", e);
            throw new RuntimeException("AES加密失败",e) ;
        }
        return resStr;
    }

    /**
     * AES解密
     *
     * @param str
     * @return
     */
    public String decryptStrWithAes(String str) {
        String resStr = null;
        try {
            byte[] raw = secretKey.getBytes(charetSet);
            SecretKeySpec key = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, key);
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] decrypted = cipher.doFinal(decoder.decodeBuffer(str));
            resStr = new String(decrypted, charetSet);
        } catch (Exception e) {
            log.error("AES解密失败", e);
            throw new RuntimeException("AES解密失败",e) ;
        }
        return resStr;
    }

    public String aesEncode(String str){

        String resStr = null;
        try {
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            random.setSeed(secretKey.getBytes(charetSet));
            KeyGenerator kGen = KeyGenerator.getInstance("AES");
            kGen.init(128, random);
            SecretKey secretKey = kGen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// 创建密码器
            byte[] byteContent = str.getBytes("utf-8");
            cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
            byte[] result = cipher.doFinal(byteContent);
            BASE64Encoder encoder = new BASE64Encoder();
            resStr= encoder.encode(result);
        } catch (Exception e){
            e.printStackTrace();
        }
        return resStr;
    }

    public String aesDecode(String str){
        String resStr = null;
        try {

            KeyGenerator kGen = KeyGenerator.getInstance("AES");
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            random.setSeed(secretKey.getBytes());
            kGen.init(128, random);
            SecretKey secretKey = kGen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// 创建密码器
            cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] decrypted = cipher.doFinal(decoder.decodeBuffer(str));
            resStr = new String(decrypted, charetSet);
        } catch (Exception e){
            e.printStackTrace();
        }
        return resStr;
    }

    /**
     * 随机生成密钥对
     * @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
        System.out.println("公钥:" + publicKeyString);
        System.out.println("私钥:" + privateKeyString);

    }
    /**
     * 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));
        //RSA加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
    }

    /**
     * RSA私钥解密
     * @param str
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static String decrypt(String str, String privateKey) throws Exception{
        //64位解码加密后的字符串
        byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
        //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.DECRYPT_MODE, priKey);
        return new String(cipher.doFinal(inputByte));
    }

    /**
     * 公钥加密
     *
     * @param content      源数据
     * @param publicKey 公钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static String encryptByPublicKey(String content, String publicKey)
            throws Exception {
        byte[] keyBytes = Base64.decodeBase64(publicKey);
        byte[] data = content.getBytes(StandardCharsets.UTF_8);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        byte[] encrypt = encrypt(data, KeyFactory.getInstance(KEY_ALGORITHM), keyFactory.generatePublic(x509KeySpec));
        return  Base64.encodeBase64String(encrypt);
    }


    /**
     * 私钥加密
     *
     * @param content       源数据
     * @param privateKey 私钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static String encryptByPrivateKey(String content, String privateKey)
            throws Exception {
        byte[] keyBytes = Base64.decodeBase64(privateKey);
        byte[] data = content.getBytes(StandardCharsets.UTF_8);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        byte[] encrypt = encrypt(data, keyFactory, privateK);
        return Base64.encodeBase64String(encrypt);
    }


    /**
     * 私钥解密
     *
     * @param content 已加密数据
     * @param privateKey    私钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static String decryptByPrivateKey(String content, String privateKey)
            throws Exception {
        byte[] keyBytes = Base64.decodeBase64(privateKey);
        //64位解码加密后的字符串
        byte[] encryptedData = Base64.decodeBase64(content.getBytes(StandardCharsets.UTF_8));
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        return new String(decrypt(encryptedData, keyFactory, keyFactory.generatePrivate(pkcs8KeySpec)));
    }


    /**
     * 公钥解密
     *
     * @param content 已加密数据
     * @param publicKey     公钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static String decryptByPublicKey(String content, String publicKey)
            throws Exception {
        byte[] keyBytes = Base64.decodeBase64(publicKey);
        //64位解码加密后的字符串
        byte[] encryptedData = Base64.decodeBase64(content.getBytes(StandardCharsets.UTF_8));
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicK = keyFactory.generatePublic(x509KeySpec);
        return new String(decrypt(encryptedData, keyFactory, publicK));

    }

    /**
     * 解密公共方法
     */
    private static byte[] decrypt(byte[] data, KeyFactory keyFactory, Key key) throws Exception {

        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, key);
        return encryptAndDecrypt(data, cipher, MAX_DECRYPT_BLOCK);
    }

    /**
     * 加密公共方法
     */
    private static byte[] encrypt(byte[] data, KeyFactory keyFactory, Key key) throws Exception {
        // 对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return encryptAndDecrypt(data, cipher, MAX_ENCRYPT_BLOCK);
    }


    /**
     * 加密解密分段处理公共方法
     */
    private static byte[] encryptAndDecrypt(byte[] data, Cipher cipher, int maxSize) throws Exception {
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = ZERO;
        byte[] cache;
        int i = ZERO;
        // 对数据分段加密
        while (inputLen - offSet > ZERO) {
            if (inputLen - offSet > maxSize) {
                cache = cipher.doFinal(data, offSet, maxSize);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, ZERO, cache.length);
            i++;
            offSet = i * maxSize;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }


    public static String decryptRSADefault(String privateKeyStr,String data) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] privateKeyArray = privateKeyStr.getBytes();
        byte[] dataArray = data.getBytes();
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyArray));
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return new String(cipher.doFinal(Base64.decodeBase64(dataArray)), StandardCharsets.UTF_8);
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            /*genKeyPair();*/
            String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDrqdHrXcgPbVvJkVfV9yyWfOsQiMSWtZRz40GUDjhiLmW6lsrU5" +
                    "HixbIc69O6ms4LL3joYnFvkvTRAkBbuMTRY6aaup6Cpsg+9HDFS6qlSPeq53VlTkoIZ990QvSL6fMyT/mwt7T66QevU8cXUHv3RT4Sbj5TclIwr2PXiom84mwIDAQAB";

String privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOup0etdyA9tW8mRV9X3LJZ86xCIxJa1lHPjQZQOOGIuZbqWytTke" +
                    "LFshzr07qazgsveOhicW+S9NECQFu4xNFjppq6noKmyD70cMVLqqVI96rndWVOSghn33RC9Ivp8zJP+bC3tPrpB69TxxdQe/dFPhJuPlNyUjCvY9eKibzibAgM" +
                    "BAAECgYAnJ9MqIS3halEq34xRj70Hz/+agq7vP4JH8wVtXSN/JKhgZTeUQdXP3PFnGVUhu4fK6cSLXEdkbQ9mfspgjypcHeV+lTzqR52oiuPEiMJPHFsSNYslorL" +
                    "ONmSWHyFGZAQe9H6Tl02GuIkSAXeruPYIHkx8WBGsIIwUeO3vRyXtUQJBAP033/PF8yAQwOJ6nnthcaaeSfu9zovPicKZ6P+5gXdBQYXX61cLqDX3gnyASZyrkgRn7" +
                    "FiZqZF2HPitPLJ+w+MCQQDuQJNYn7zt09E2fEvNjzWobt2oilpn/rDPzEzeaSGg1soxWt7KLWFqNfL+t++iUvlj+Kzx3I+o36HQK32vroXpAkABh7DmvC935iIEPFFw1" +
                    "WnmY9Z2mvMAjUR71Io/4VMS8WX/9QoLAJsHmHNFZVEMjUzYkfgvoN4RbvFF32YafgGZAkAAgG5O/3ccYRfNr5FRS33nbuRUmIX8NhMVPO7kgQArIIiodfKGJnZQDPEID" +
                    "Eca5mXUChADKl27E0157L2FAy8RAkAmnqO1yH+jN0dYccz6CibH0ReTjFNddojHqMxzl/ohDlCBTtn3RPHnzVz4U7iOh15Ka4JCVh+mMYtVoA9rgZwl";

            String content = "aRiSY6lzi0k/VfnSRc25R31pp4rEHfx633+E/vUF7yzzD9Gdblgn295jdvHn4eSB/uuDpYmwNQkpjYpaMCXJOJ6f2/Pp3uJEvurgnOOOoGw6OUHEUQh3YCYngWGi8jbwtXs0D5OZw1S6zQQAFWMMpzReMdEt67DcNOqvIe68xmCVTvfJhnW7lzFRrtcMe2w8ia8vYLJwlfr2fA1OfJlI+h6obEyVSFJhISTmccfkCCNqbZNnlzow2jA+NMkGoLnXXdOAnWspo7E/OV2mKkOhXxmFsUTCPE4ToC41N47VLn6Lc7byyYyMhPO4ZsmFI1tZAH01OiF+hMGgaHGzhHySpQ==";
            String decrypt = decryptByPrivateKey(content,privateKey);
            System.out.println("解密结果:" + decrypt);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值