javax.crypto.BadPaddingException : Decryption error

客户端将参数加密后通过http方式调用接口,接口服务方在获取参数进行解密时发生这个错误

发现主要原因为:

    原始加密参数值为:

         例如:dkjgoeFGKJ+ERO7/999JLJkjk==

    获取的加密参数值为:

                 dkjgoeFGKJ  ERO7/999JLJkjk==

    注意到是+位置获取后试空格了

解决方式:

     我采用的是加密时将密文字符串进行一次替换:如:str.replaceAll("[+]", "@");

     注意:替换的字符 ,必须是rsa加密后转成字符串时不会存在的字符,比如,你不能将+替换为a等,因为我的密文是大小写字母,数字,/,+,=组成的.

获取方在获取后再进行替换:str.replaceAll("@", "+");

如果大家有更好的方式,欢迎留言.

代码示例:


import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

@SuppressWarnings("restriction")
public abstract class RSACoder  {  
    private static final String KEY_ALGORITHM = "RSA";
	private static final int MAX_ENCRYPT_1024 = 117;
	private static final int MAX_DECRYPT_1024 = 128;
//	private static final int MAX_ENCRYPT_2048 = 245;
//	private static final int MAX_DECRYPT_2048 = 256;
      
    private static byte[] decryptBASE64(String src) {
		BASE64Decoder decoder = new BASE64Decoder();
		try {
			return decoder.decodeBuffer(src);
		} catch (Exception ex) {
			return null;
		}

	}
    /**
	 * 该base64方法会自动换行
	 * @param src
	 * @return
	 */
	private static String encryptBASE64(byte[] src) {
		BASE64Encoder encoder = new BASE64Encoder();

		return encoder.encode(src);
	}
    /**
     * 公钥分段加密 
     * @param data 源数据 
     * @param publicKey 公钥(BASE64编码) 
     * @param length 段长  
     * @return 
     * @throws Exception 
     */  
    private static byte[] encryptByPublicKey(byte[] data, String publicKey,int length)  
            throws Exception {
        byte[] keyBytes = decryptBASE64(publicKey);  
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);  
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
        Key publicK = keyFactory.generatePublic(x509KeySpec);  
        // 对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
        cipher.init(Cipher.ENCRYPT_MODE, publicK);  
        int inputLen = data.length;  
        ByteArrayOutputStream out = new ByteArrayOutputStream();  
        int offSet = 0;  
        byte[] cache;  
        int i = 0;  
        // 对数据分段加密
        while (inputLen - offSet > 0) {  
            if (inputLen - offSet > length) {  
                cache = cipher.doFinal(data, offSet, length);  
            } else {  
                cache = cipher.doFinal(data, offSet, inputLen - offSet);  
            }  
            out.write(cache, 0, cache.length);  
            i++;  
            offSet = i * length;  
        }  
        byte[] encryptData = out.toByteArray();
        out.close();
        return encryptData;
    } 
    
    /** *//**
     * <P>
     * 私钥解密
     * </p>
     * 
     * @param encryptedData 已加密数据
     * @param privateKey 私钥(BASE64编码)
     * @return
     * @throws Exception
     */
    private static byte[] decryptByPrivateKey(byte[] data, String privateKey,int length)
            throws Exception {
        byte[] keyBytes =  decryptBASE64(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateK);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > length) {
                cache = cipher.doFinal(data, offSet, length);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * length;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }

	/**
	 * 加密
	 * @param data
	 * @param publicKey
	 * @return
	 */
	public static String encryptByPublicKey(String data, String publicKey) {
		return encryptBASE64(encryptByPublicKey(data.getBytes(), publicKey, MAX_ENCRYPT_1024)).replaceAll("[+]", "@");
	}

	/**
	 * 解密
	 * @param data
	 * @param publicKey
	 * @return
	 */
	public static String decryptByPrivateKey(String data, String privateKey) {
		return new String(decryptByPrivateKey(decryptBASE64(data.replaceAll("@", "+")), privateKey, MAX_DECRYPT_1024));
	}
	
}  

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值