{"record":{"id":"47bca0b801ec90aa","repo":"binarywang/WxJava","slug":"aes-cbc-encrypt-failed","errorCode":null,"errorMessage":"AES CBC encrypt failed","messagePattern":"AES CBC encrypt failed","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"weixin-java-aispeech/src/main/java/me/chanjar/weixin/aispeech/util/WxAispeechSignUtil.java","lineNumber":43,"sourceCode":"      + defaultString(requestBody);\n    try {\n      Mac mac = Mac.getInstance(\"HmacSHA256\");\n      mac.init(new SecretKeySpec(defaultString(secretKey).getBytes(StandardCharsets.UTF_8), \"HmacSHA256\"));\n      return bytesToHex(mac.doFinal(payload.getBytes(StandardCharsets.UTF_8)));\n    } catch (GeneralSecurityException e) {\n      throw new IllegalStateException(\"HmacSHA256 signature failed\", e);\n    }\n  }\n\n  public static String encryptAesCbcToBase64(String plainText, String aesKey) {\n    try {\n      byte[] keyBytes = decodeAesKey(aesKey);\n      Cipher cipher = Cipher.getInstance(\"AES/CBC/PKCS5Padding\");\n      cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, \"AES\"), new IvParameterSpec(Arrays.copyOf(keyBytes, 16)));\n      byte[] encrypted = cipher.doFinal(defaultString(plainText).getBytes(StandardCharsets.UTF_8));\n      return Base64.encodeBase64String(encrypted);\n    } catch (GeneralSecurityException e) {\n      throw new IllegalStateException(\"AES CBC encrypt failed\", e);\n    }\n  }\n\n  public static String decryptAesCbcFromBase64(String cipherTextBase64, String aesKey) {\n    try {\n      byte[] keyBytes = decodeAesKey(aesKey);\n      Cipher cipher = Cipher.getInstance(\"AES/CBC/PKCS5Padding\");\n      cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, \"AES\"), new IvParameterSpec(Arrays.copyOf(keyBytes, 16)));\n      byte[] encrypted = Base64.decodeBase64(defaultString(cipherTextBase64));\n      return new String(cipher.doFinal(encrypted), StandardCharsets.UTF_8);\n    } catch (GeneralSecurityException e) {\n      throw new IllegalStateException(\"AES CBC decrypt failed\", e);\n    }\n  }\n\n  private static byte[] decodeAesKey(String aesKey) {\n    return Base64.decodeBase64(defaultString(aesKey) + \"=\");\n  }","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/binarywang/WxJava/blob/1c43293a3c2c9d7e91304b6d037fb017f680d0c6/weixin-java-aispeech/src/main/java/me/chanjar/weixin/aispeech/util/WxAispeechSignUtil.java#L25-L61","documentation":"Thrown by `encryptAesCbcToBase64` when AES/CBC/PKCS5Padding encryption fails (GeneralSecurityException wrapped as IllegalStateException). The key is derived by base64-decoding `aesKey + \"=\"`, so the usual cause is an invalid/incorrectly-padded key, a wrong key length, or an unusable provider.","triggerScenarios":"Passing an aesKey that is not valid base64, has the wrong bit length after decoding (AES needs 16/24/32 bytes), or a tampered key string. The IV is the first 16 bytes of the key, so a short key also breaks IV init.","commonSituations":"Wrong key copied from console (truncated/whitespace); key encoded differently than expected; secret rotated but client not updated.","solutions":["Verify the aesKey decodes cleanly from base64 to 16/24/32 bytes.","Trim whitespace/newlines from the key before passing it.","Confirm the key matches what the server expects for this session.","Inspect the wrapped GeneralSecurityException cause (InvalidKeyException vs IllegalBlockSizeException)."],"exampleFix":"// before\nString c = WxAispeechSignUtil.encryptAesCbcToBase64(plain, \"not-valid-base64!!\");  // throws\n// after\nString key = aesKey.trim();  // ensure clean, valid base64 decoding to 16/24/32 bytes\nString c = WxAispeechSignUtil.encryptAesCbcToBase64(plain, key);","handlingStrategy":"try-catch","validationCode":"// Validate the AES key before encrypting\nbyte[] keyBytes = java.util.Base64.getDecoder().decode(aesKey.trim() + \"=\");\nif (keyBytes.length != 16 && keyBytes.length != 24 && keyBytes.length != 32) {\n    throw new IllegalArgumentException(\"Invalid AES key length: \" + keyBytes.length);\n}","typeGuard":null,"tryCatchPattern":"try {\n    String cipher = WxAispeechSignUtil.encryptAesCbcToBase64(plain, aesKey);\n} catch (IllegalStateException e) {\n    // cause is InvalidKeyException / IllegalBlockSizeException etc.\n    log.error(\"AES encrypt failed, likely bad key\", e.getCause());\n    throw e;\n}","preventionTips":["Trim whitespace from keys before use.","Verify base64 decodes to a valid AES key length.","Keep client and server keys in sync after rotation."],"tags":["aispeech","crypto","aes","runtime"],"backgroundTag":null,"analyzedSha":"1c43293a3c2c9d7e91304b6d037fb017f680d0c6","analyzedAt":"2026-08-14T02:29:11.060Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}