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;
    } 
    
    /** *//**
     * 

* 私钥解密 *

* * @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)); } }

 

你可能感兴趣的:(异常)