binarywang/WxJava · critical · IllegalStateException
HmacSHA256 signature failed
Error message
HmacSHA256 signature failed
What it means
Thrown by `calcKnowledgeSignature` when the JCE `Mac.getInstance("HmacSHA256")` or `mac.init(...)` raises a GeneralSecurityException, wrapped as IllegalStateException. HmacSHA256 is mandatory in every JDK, so in practice this only fires on a corrupted/custom security provider, a bad SecretKeySpec, or a severely misconfigured JVM.
Source
Thrown at weixin-java-aispeech/src/main/java/me/chanjar/weixin/aispeech/util/WxAispeechSignUtil.java:31
public final class WxAispeechSignUtil {
private WxAispeechSignUtil() {
}
public static String calcDialogSign(String token, long timestamp, String nonce, String body) {
String bodyMd5 = DigestUtils.md5Hex(defaultString(body));
return DigestUtils.md5Hex(defaultString(token) + timestamp + defaultString(nonce) + bodyMd5);
}
public static String calcKnowledgeSignature(String secretKey, long timestamp, String nonce, String requestId,
String requestBody) {
String payload = timestamp + "\n" + defaultString(nonce) + "\n" + defaultString(requestId) + "\n"
+ defaultString(requestBody);
try {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(defaultString(secretKey).getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
return bytesToHex(mac.doFinal(payload.getBytes(StandardCharsets.UTF_8)));
} catch (GeneralSecurityException e) {
throw new IllegalStateException("HmacSHA256 signature failed", e);
}
}
public static String encryptAesCbcToBase64(String plainText, String aesKey) {
try {
byte[] keyBytes = decodeAesKey(aesKey);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), new IvParameterSpec(Arrays.copyOf(keyBytes, 16)));
byte[] encrypted = cipher.doFinal(defaultString(plainText).getBytes(StandardCharsets.UTF_8));
return Base64.encodeBase64String(encrypted);
} catch (GeneralSecurityException e) {
throw new IllegalStateException("AES CBC encrypt failed", e);
}
}
public static String decryptAesCbcFromBase64(String cipherTextBase64, String aesKey) {
try {
byte[] keyBytes = decodeAesKey(aesKey);View on GitHub (pinned to 1c43293a3c)
Solutions
- Confirm the JVM provides HmacSHA256: run a tiny `Mac.getInstance("HmacSHA256")` test.
- Remove or fix any custom security provider registered via `java.security`.
- Use a standard JDK distribution rather than a stripped image.
- Inspect the wrapped cause exception for the exact algorithm/provider error.
Defensive patterns
Strategy: try-catch
Validate before calling
// Sanity-check the JCE provider at startup
try {
javax.crypto.Mac.getInstance("HmacSHA256");
} catch (java.security.NoSuchAlgorithmException e) {
throw new IllegalStateException("JVM lacks HmacSHA256", e);
} Try / catch
try {
String sig = WxAispeechSignUtil.calcKnowledgeSignature(secretKey, ts, nonce, reqId, body);
} catch (IllegalStateException e) {
// unwrap GeneralSecurityException; provider/algorithm problem
log.error("HmacSHA256 unavailable on this JVM", e.getCause());
throw e;
} Prevention
- Run on a standard, unstripped JDK.
- Avoid registering custom JCE providers that drop HmacSHA256.
- Add a startup self-test for required crypto algorithms.
When it happens
Trigger: An exotic JCE provider that does not implement HmacSHA256; a SecurityManager/provider override stripping algorithms; running on a stripped JVM image lacking the HmacSHA256 algorithm.
Common situations: Custom/JNI security provider misconfigured; hardened/restricted JRE; rarely a JDK bug.
Related errors
- AES CBC encrypt failed
- AES CBC decrypt failed
- 响应为空
- X-OPENAI-TOKEN不能为空,请先调用getAccessToken或手动设置
- X-APPID不能为空
AI-assisted analysis of binarywang/WxJava@1c43293a3c (2026-08-14).
Data as JSON: /api/errors/b428b42be539b4e6.
Report an issue: GitHub.