commons-codec 1.13 版本不能正常解密微信的消息
Base64编码异常bug
base64是一种基本的加密算法,在Java中可以使用java自带的base64编码,也可以用apache 的commons-codec包。最近在使用commons-codec 1.10 版本能正常解密微信的消息,升级为1.13后出现了不能正常decode,出现异常。
具体场景
/**
* 私钥解密
*
* @param data 待解密的数据
* @param priKey 私钥
* @return
* @throws Exception
*/
public static byte[] decryptByPriKey(byte[] data, byte[] priKey) throws Exception {
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 私钥解密
*
* @param data 解密前的字符串
* @param privateKey 私钥
* @return 解密后的字符串
* @throws Exception
*/
public static String decryptByPriKey(String data, String privateKey) throws Exception {
byte[] priKey = RSAUtil.decodeBase64(privateKey);
byte[] design = decryptByPriKey(Base64.decodeBase64(data), priKey);
return new String(design);
}
public static void main(String[] args) throws Exception {
String priKey = "-----BEGIN RSA PRIVATE KEY-----\n" +
"MIIEpgIBAAKCAQEAz9G3xACyOacgacUo7vFZTHoRv1vyk9ZjM+/hFr6YOfiPocCE\n" +
"jgm+uAwyTio4rlBFsx4qM3AxPjfw5sMUPZ2xODb6/1hVZ4ggp3WbjkCUmC5jdvCE\n" +
"cDun9rQ7PbR9sZChqnm4p6GhVyfUlxcoJdBDRzz81V9PFUOidYIKqVThUMCAXizu\n" +
"m3yrC6xlFJs66o8t9gazI1ZrvSg0N4/NmDx77fsvmd2E2QmhN5Nay2mOn5IhNOsZ\n" +
"9IIeEKRm47b6HOEQJCuDYjwfAf29nXfZKJGkE7jX1P50Xy3XNdkt99DK3W77ZWcX\n" +
"lu0aiR9mFks2c8wgniaVOVpFuKiWkOz+dRUgAQIDAQABAoIBAQCNtOMps4/T4DIp\n" +
"7VbMF6Zcj6Aqa/gs9rMOZzOE3tHONb86/Jtmfx6dQTPMON4Nfo8IZDlCee4aDusl\n" +
"b0AOA8kkG9lq5EDYJ+qcRYWcqkyouHj6UWb9YLBXeO4sVTagLY8PP5C6PWxWkcJU\n" +
"hGXL4wb9PIjqteKnDUdp+RJsBITfGilNrWmkU9hJCt4BLyJ8bUjtpdGcRvC0w1fN\n" +
"W3wFMQS1FZv+MX1zvMV29hReHNlRW4vStBQNaZykBITm0jf9fqvIP44cWFwO5Gac\n" +
"kbg4NGes0QEAocTqpWQN1HRsLB316bOpGpShCMqqsnpxCbx/4zGB9Y5f0r7+umC1\n" +
"evjGai9BAoGBAPTqjFwIGtzBJU4yH/MF/5LFWKEkzuU36zydI8X9AQYw3UCR3o5m\n" +
"6XxuG9yHDdGUeoPBS1SSsv9uMG0TMStsbfaZ9JDtgzYMbOkYUVkyxzuM3zFo5QTR\n" +
"Pc+QCaEOYFS57QKM4+OnhxGSte/9/uhymXze1Y6Fzpt7nLcvpNlyLMBzAoGBANk5\n" +
"YthRODZun24S5KqKvNq87Gbbd5gkswrBcwicWWASkxDsPPK/4mfEc3yvUOFZnXOS\n" +
"+LtiAXlMMkw91F1m5ubnu3Kd7mPUqHJB6uUX6BspIFSneklDFfvOLtyPD8vTuLqA\n" +
"n3JJmsNIXsyw+dOtm5RpNZ5dMpSZSsDEY3f0IkS7AoGBAKkBUWoQjbjX745OOI3T\n" +
"DdGSLN7GL58tPz7MkOsG87X58jOkdRd/HI+oy8EZ0QdWllRlBj6OHMb2mqQqIjv8\n" +
"zsTk6Ec6HtklKeKPzVLoH2OQilPmNmNkoGqi0oI5EXBl/I9N+dQWvrX5r2K0uzpc\n" +
"Gl54xpVa8H+KhVJDplYG26rRAoGBAKNFMdlber/W9/g5NSxGKVrTw3AwJzzw4K4F\n" +
"5xuiwL6oV2fR2KGwvlC2ZQNjlow62lCjOFdHe8obDnclxfgKPyVxKgAlWqgokA+J\n" +
"Ii/dfzTi/Y0DcLOeO+jO+YQH95yBX4i24qF5V1zOiYqavrxu8dBkH8wPStRMP9aS\n" +
"Bh2EHzm/AoGBAPM3hk3XCanYcVCDyOHOMSyA/6CiG3+09vKyaM5ZPmEE32mnsz50\n" +
"DetKm7hzFZ4FRBplSrIxLWIvjhillpCKoe1gg+rMAeS/MYHoWuWhpLZRnkzJxKDK\n" +
"VMNCOSxXfMnYFVtijIEPG89FfMuicec7Lub2HnH/jaxWf/w4d3zqzFgr\n" +
"-----END RSA PRIVATE KEY-----\n";
String secStr = "UDLFPrFBe6sDI52eVoZ01EqJg7vsFsj/PXpwVIZywvefOpfaJJY9BdM83NMjJ3eCTd1Oyr4OTtgzh/YblpFKp45lJwCMv/p5Q12Pnoc3m/fe5ht0DpsilvnPGzl4dCA6oSTquVxsksn0oH4+TnIjiaCi2PY+DB8kKPVOnC2opta6YG3BYs25kI7ijM+OQ5CMoyTJTxHc1MFwo/8r+AlUuFVlyBLay6LxYKNImTi1HzzsRqRtWMNkRqUzSzCcaFUC/XqeYCBpgD9m0iyvexDs08it2iL0JK2AGkw74tkFxfF7QKB9aMzDCbpmKsA/DwoBnxzK1nyMvOp5k6myuWQyKA==";
String s = decryptByPriKey(secStr, priKey);
System.out.println(s);
}
运行出现下面控制太问题
出现的原因
以下这是 1.13版本的Base源码
下面可以看出编解码是在BaseNCodec.class是Base64
唯一的差别就是在解码时对参数做了校验。有必要了解下这个参数校验做了些什么?
if ((context.ibitWorkArea & numBitsToDrop) != 0) {}
ibitWorkArea: 位处理的基本位数
numBitsToDrop: 应该为空的低位数目
可以看出当 context.ibitWorkArea & numBitsToDrop不为0时就会抛出异常,实际上只有base64严格模式编码下,才可能会为0,松散模式不会为0