RSA解密时BadPaddingException解决方法

工作的时候遇到程序需要进行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眅@XJ佗D=w?桠嫟O褫?鄾埔4	?w?8I嵀鶮)0+镔霉暺`趕Y緤u侼桝?两?1鏷
解密后文字: 
<manifest xmlns:android="http://schemas.android.com/apk/res/android"




  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值