有些朋友可能遇到了下面的错误:
pad block corrupted
或者
last block incomplete in decryption
这很有可能是编码错误导致的
微信支付将req_info进行base64编码时,用的字符集不是UTF-8, 而是ISO-8859-1
如果你用UTF-8进行解码, 就一定会报错.
原因是:
将一个byte[]转换成String, 然后再从String转换为byte[]时,
第一个byte[]的值和第二个byte[]的值是不同的,
除非你指定字符集为ISO-8859-1, 或者默认字符集为ISO-8859-1.
由于UTF-8是多字节编码,需要用多个字节来表示一个字符的编码,所以也就出现了在转换之后byte[]数组长度、内容不一致的情况。
而ISO-8859-1编码是单字节编码,所以使用该编码就不会出现上面的问题
详情见下贴:
https://blog.csdn.net/qq_27760433/article/details/78327328
怎样解决这个问题呢?
方法有两种:
(1),
如果你使用java 8 自带的java.util.Base64类,
例如:
Base64.Decoder decoder = Base64.getDecoder();
pad block corrupted
或者
last block incomplete in decryption
这很有可能是编码错误导致的
微信支付将req_info进行base64编码时,用的字符集不是UTF-8, 而是ISO-8859-1
如果你用UTF-8进行解码, 就一定会报错.
原因是:
将一个byte[]转换成String, 然后再从String转换为byte[]时,
第一个byte[]的值和第二个byte[]的值是不同的,
除非你指定字符集为ISO-8859-1, 或者默认字符集为ISO-8859-1.
由于UTF-8是多字节编码,需要用多个字节来表示一个字符的编码,所以也就出现了在转换之后byte[]数组长度、内容不一致的情况。
而ISO-8859-1编码是单字节编码,所以使用该编码就不会出现上面的问题
详情见下贴:
https://blog.csdn.net/qq_27760433/article/details/78327328
怎样解决这个问题呢?
方法有两种:
(1),
如果你使用java 8 自带的java.util.Base64类,
例如:
Base64.Decoder decoder = Base64.getDecoder();
那么解密方法这么写:
public static String decryptData(final String base64Data) throws Exception
{
final Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING, "BC");
cipher.init(Cipher.DECRYPT_MODE, key);
return new String(cipher.doFinal(CyptoUtil.base64_decode_8859(base64Data).getBytes("ISO-8859-1")), "utf-8");
//注意:第一个是ISO-8859-1,第二个是utf-8
}
上面的CyptoUtil.base64_decode_8859的定义如下:
public static String base64_decode_8859(final String source)
{
String result = "";
final Base64.Decoder decoder = Base64.getDecoder();
try
{
result = new String(decoder.decode(source), "ISO-8859-1");
//此处的字符集是ISO-8859-1
}
catch (final UnsupportedEncodingException e)
{
e.printStackTrace();
}
return result;
}
对应地, 加密的方法这么写:
public static String encryptData(final String data) throws Exception
{
// 创建密码器
final Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING, "BC");
// 初始化
cipher.init(Cipher.ENCRYPT_MODE, key);
return CyptoUtil.base64_encode_8859(new String(cipher.doFinal(data.getBytes()), "ISO-8859-1"));
}
上面的CyptoUtil.base64_encode_8859()定义如下:
public static String base64_encode_8859(final String source)
{
String result = "";
final Base64.Encoder encoder = Base64.getEncoder();
byte[] textByte = null;
try
{
textByte = source.getBytes("ISO-8859-1");
//注意此处的编码是ISO-8859-1
}
catch (final UnsupportedEncodingException e)
{
e.printStackTrace();
}
result = encoder.encodeToString(textByte);
return result;
}
(2),
第二种方法是: 不要用java 8 自带的java.util.Base64类, 而找一个其他人写好的Base64Util工具类
例如这个:
https://blog.csdn.net/m0_37218608/article/details/79505068
两种方法我个人推荐第一种, 毕竟是JAVA官方提供的,值得信赖!
本文主要想强调编码错误, 其余代码请参考:
https://blog.csdn.net/u010660575/article/details/76672402