查看项目依赖,检查项目中的commons-codec版本。
引起这个报错的原因主要是org.apache.commons.codec.binary.Base64类。
1.13之前的版本的decode方法:
if (context.eof && context.modulus != 0) {
byte[] buffer = this.ensureBufferSize(this.decodeSize, context);
switch(context.modulus) {
case 1:
break;
case 2:
context.ibitWorkArea >>= 4;
buffer[context.pos++] = (byte)(context.ibitWorkArea & 255);
break;
case 3:
context.ibitWorkArea >>= 2;
buffer[context.pos++] = (byte)(context.ibitWorkArea >> 8 & 255);
buffer[context.pos++] = (byte)(context.ibitWorkArea & 255);
break;
default:
throw new IllegalStateException("Impossible modulus " + context.modulus);
}
}
1.13的decode方法:
if (context.eof && context.modulus != 0) {
final byte[] buffer = ensureBufferSize(decodeSize, context);
// We have some spare bits remaining
// Output all whole multiples of 8 bits and ignore the rest
switch (context.modulus) {
// case 0 : // impossible, as excluded above
case 1 : // 6 bits - either ignore entirely, or raise an exception
validateTrailingCharacter();
break;
case 2 : // 12 bits = 8 + 4
validateCharacter(MASK_4BITS, context);
context.ibitWorkArea = context.ibitWorkArea >> 4; // dump the extra 4 bits
buffer[context.pos++] = (byte) ((context.ibitWorkArea) & MASK_8BITS);
break;
case 3 : // 18 bits = 8 + 8 + 2
validateCharacter(MASK_2BITS, context);
context.ibitWorkArea = context.ibitWorkArea >> 2; // dump 2 bits
buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 8) & MASK_8BITS);
buffer[context.pos++] = (byte) ((context.ibitWorkArea) & MASK_8BITS);
break;
default:
throw new IllegalStateException("Impossible modulus " + context.modulus);
}
}
相比旧版多了一次校验,源码如下:
/**
* Validates whether decoding the final trailing character is possible in the context
* of the set of possible base 64 values.
*
* <p>The character is valid if the lower bits within the provided mask are zero. This
* is used to test the final trailing base-64 digit is zero in the bits that will be discarded.
*
* @param emptyBitsMask The mask of the lower bits that should be empty
* @param context the context to be used
*
* @throws IllegalArgumentException if the bits being checked contain any non-zero value
*/
private void validateCharacter(final int emptyBitsMask, final Context context) {
if (isStrictDecoding() && (context.ibitWorkArea & emptyBitsMask) != 0) {
throw new IllegalArgumentException(
"Strict decoding: Last encoded character (before the paddings if any) is a valid " +
"base 64 alphabet but not a possible encoding. " +
"Expected the discarded bits from the character to be zero.");
}
}
/**
* Validates whether decoding allows an entire final trailing character that cannot be
* used for a complete byte.
*
* @throws IllegalArgumentException if strict decoding is enabled
*/
private void validateTrailingCharacter() {
if (isStrictDecoding()) {
throw new IllegalArgumentException(
"Strict decoding: Last encoded character (before the paddings if any) is a valid " +
"base 64 alphabet but not a possible encoding. " +
"Decoding requires at least two trailing 6-bit characters to create bytes.");
}
}
这一段代码的作用是:来验证在上下文中是否可以解码最后的尾随字符。钉钉生成的是43位的aeskey,然后通过官方的sdk最后补充了一位“=”,无法通过校验,如果修改最后的补位又会导致签名无法通过……
解决的办法
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<exclusions>
<exclusion>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</exclusion>
</exclusions>
<version>3.1</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
另外如果不是钉钉开发的话,可以改变靠aeskey来解决这个问题。