RSA解密时BadPaddingException解决方法
2023-02-18 16:45:39 时间
工作的时候遇到程序需要进行RSA加密解密的部分,在写第一版测试的时候,出现了:
- Exception in thread "main" javax.crypto.BadPaddingException: Data must start with zero
- at sun.security.rsa.RSAPadding.unpadV15(Unknown Source)
- at sun.security.rsa.RSAPadding.unpad(Unknown Source)
- at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
- at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
- at javax.crypto.Cipher.doFinal(DashoA13*..)
- at com.pack.RSAUtils.decryptByPrivateKey(RSAUtils.java:164)
- at com.pack.RSATest.test(RSATest.java:47)
- at com.pack.RSATest.main(RSATest.java:26)
这样一个错误,
代码:
- package com.pack;
-
- import java.io.File;
- import java.util.Map;
-
- public class RSATest {
- static String publicKey;
- static String privateKey;
-
- static {
- try {
- Map<String, Object> keyMap = RSAUtils.genKeyPair();
- publicKey = RSAUtils.getPublicKey(keyMap);
- privateKey = RSAUtils.getPrivateKey(keyMap);
- System.err.println("公钥: \n\r" + publicKey);
- System.err.println("私钥: \n\r" + privateKey);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
-
- public static void main(String[] args) throws Exception {
- test();
- }
-
- static void test() throws Exception {
- System.err.println("公钥加密——私钥解密");
- String source = "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"";
- System.out.println("\r加密前文字:\r\n" + source);
- byte[] data = source.getBytes();
- byte[] encodedData = RSAUtils.encryptByPublicKey(data, publicKey);
- System.out.println("加密后文字:\r\n" + new String(encodedData));
- String str = new String(encodedData);
- byte[] decodedData = RSAUtils.decryptByPrivateKey(str.getBytes(), privateKey);
- String target = new String(decodedData);
- System.out.println("解密后文字: \r\n" + target);
- }
}
但是如果我把加密后的byte数组直接解密,就没有问题,到网上找了很多,但是没有说的特别明白的帖子,后来在http://www.myexception.cn/java-other/BadPaddingException.html这里 看到了一个还算说的明白的帖子,
其实就是因为把byte[]数组转化成字符串,写入到文件,但是从字符串转化成byte[]数组的时候,程序无法找到每一个byte[]里元素的临界点在哪里,所以知道了这一点,要解决这个问题也就简单了,就是在加密之后的byte[]元素之间加上一个标志符,可以使空格,也可以是0,.然后在解密的时候要进行字符串的拆分,组装成byte[]数组,然后再进行解密。就可以搞定了。
所有就有了下面的方法:
- package com.pack;
-
- import java.io.BufferedReader;
- import java.io.BufferedWriter;
- import java.io.File;
- import java.io.FileReader;
- import java.io.FileWriter;
- import java.io.IOException;
- import java.util.Map;
-
-
- /**
- * RSA对文件或字符串进行加密解密功�?
- * @author 胡松振
- *
- */
- public class RSAUtil {
-
-
- // 把byte[]元素之间添加空格,并转化成字符串返回,
- public String byteToString(byte[] resouce){
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < resouce.length; i++) {
- if (i == resouce.length-1) {
- sb.append(Byte.toString(resouce[i]));
- }else{
- sb.append(Byte.toString(resouce[i]));
- sb.append(" ");
- }
- }
- return sb.toString();
-
- }
-
- // 把字符串按照空格进行拆分成数组,然后转化成byte[],返回
- public byte[] stringToByte(String resouce){
- String[] strArr = resouce.split(" ");
- int len = strArr.length;
- byte[] clone = new byte[len];
- for (int i = 0; i < len; i++) {
- clone[i] = Byte.parseByte(strArr[i]);
- }
-
- return clone;
-
- }
- }
那下面就是见证奇迹的时刻了:
- static void test() throws Exception {
- RSAUtil ru = new RSAUtil();
- System.err.println("公钥加密——私钥解密");
- String source = "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"";
- System.out.println("\r加密前文字:\r\n" + source);
- byte[] data = source.getBytes();
- byte[] encodedData = RSAUtils.encryptByPublicKey(data, publicKey);
- System.out.println("加密后文字:\r\n" + new String(encodedData));
- String str = ru.byteToString(encodedData);
- byte[] resource = ru.stringToByte(str);
- byte[] decodedData = RSAUtils.decryptByPrivateKey(resource, privateKey);
- String target = new String(decodedData);
- System.out.println("解密后文字: \r\n" + target);
- }
下面的结果就正确了:
- 加密前文字:
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- 加密后文字:
- 殞獒郵L崭'34?︱}库珃??\茕y?曘肭蚐?堏?'d/B眅@XJ佗D=w?桠嫟O褫?鄾埔4 ?w?8I嵀鶮)0+镔霉暺`趕Y緤u侼桝?两?1鏷
- 解密后文字:
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
相关文章
- vue2搭配vue-router3真正可用不报错的写法格式
- wordpress跨境电商外贸独立站安装WooCommerce插件
- wordpress独立网站域名解析教程
- obs直播录屏软件下载使用教程-制作短视频录制视频教程
- wordpress独立站菜单导航设置教程
- wordpress外贸跨境电商独立站WooCommerce插件安装教程
- wordpress编辑器增加粘贴图片上传服务器教程
- wordpress网站主题安装教程
- 多语言在线客服系统源码-自动识别中英环境-私有化部署完美支持跨境电商网站
- wordpress企业网站搭建教程
- 自动发货发卡系统搭建教程
- 设置display:flex后 flex布局设置单个子元素靠右
- X-Content-Type-Options: nosniff 禁用浏览器类型猜测保证安全性
- 网页在线客服代码-侧边悬浮在线客服/QQ/微信/电话代码
- getUserMedia报错:新版本Chrome中getUserMedia接口在http下不再支持
- elementui的confirm确认框的使用方式
- getUserMedia()出现的常见错误
- php安装向导中判断是否安装的实现思路
- 一款强大的网页在线客服聊天系统:唯一客服搭建教程
- 仿美洽客服系统-gin框架内核独立自主源码开发在线客服系统