RSA解密时报错javax.crypto.BadPaddingException: Decryption error

远天战歌 2022-01-27 11:41:22

在使用2048位公钥私钥进行解密时出现javax.crypto.BadPaddingException: Decryption error,根据网上提供的信息是由于加密和解密填充的内容不一致导致的,但是目前没有解决办法,不知道问题出在哪?

//加密算法RSA
public static final String KEY_ALGORITHM = "RSA";

//RSA最大加密明文大小
private static final int MAX_ENCRYPT_BLOCK = 117;

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

public static String encryptByPublicKey(String dataBase64String, String publicKey) throws Exception {
//base64编码的公钥
byte[] decoded = Base64.decodeBase64(publicKey);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));

byte[] data = dataBase64String.getBytes();
//        byte[] keyBytes = java.util.Base64.getDecoder().decode(publicKey);
//        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
//        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//        Key publicK = keyFactory.generatePublic(x509KeySpec);
        // 对数据加密
//        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
   if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
       cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
   } else {
       cache = cipher.doFinal(data, offSet, inputLen - offSet);
   }
   out.write(cache, 0, cache.length);
   i++;
   offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return java.util.Base64.getEncoder().encodeToString(encryptedData);
}


public static String decryptByPrivateKey(String encryptedDataString, String privateKey) throws Exception {
//64位解码加密后的字符串
byte[] encryptedData = Base64.decodeBase64(encryptedDataString.getBytes("UTF-8"));
//base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));

//应该先使用Base64方式进行解码
//        byte[] encryptedData = encryptedDataString.getBytes();
//        byte[] keyBytes = java.util.Base64.getDecoder().decode(privateKey);
//        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
//        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
//        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        int inputLen = encryptedData.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(encryptedData, offSet, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return new String(decryptedData);
    }

public static void main(String[] args) {
try {

String data = "测试内容测试内容";
String encryptData = encryptByPublicKey(data, wfgy);
System.out.println("加密后内容:" + encryptData);
// RSA解密
String decryptData = decryptByPrivateKey(encryptData, wfsy);
            System.out.println("解密后内容:" + decryptData);
            // RSA签名
            String sign = sign(data, getPrivateKey(wfsy));
            // RSA验签
            boolean result = verify(data, getPublicKey(wfgy), sign);
            System.out.print("验签结果:" + result);
} catch (Exception e) {
            e.printStackTrace();
            System.out.print("加解密异常");
        }
    }

 

...全文
7227 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
gy坏坏 2024-11-12
  • 打赏
  • 举报
回复

MAX_DECRYPT_BLOCK 需要密钥长度8分之一
2048 对应256

幻灰龙 2023-06-02
  • 打赏
  • 举报
回复

@CSDN-Ada助手请解决这个问题

CSDN-Ada助手 2023-06-02
  • 举报
回复
@幻灰龙 根据您提供的代码片段,我看到您在进行加密和解密时使用的是RSA算法,最大加密明文大小为117字节,最大解密密文大小为128字节。根据异常信息提示,可能是加密和解密填充的内容不一致导致的。您可以尝试检查加密时的填充模式是否与解密时的填充模式一致,比如都使用PKCS1Padding填充模式。如果还不能解决问题,您可以尝试使用更长的密钥长度进行加密,比如4096位密钥长度,或者使用其他的加密算法进行加密和解密。
  • 打赏
  • 举报
回复

解决了吗

CSDN-Ada助手 2023-01-13
  • 打赏
  • 举报
回复
您可以前往 CSDN问答-Java 发布问题, 以便更快地解决您的疑问

67,544

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧