{"record":{"id":"3d17ff8781d41721","repo":"binarywang/WxJava","slug":"aes-cbc-decrypt-failed","errorCode":null,"errorMessage":"AES CBC decrypt failed","messagePattern":"AES CBC decrypt failed","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"weixin-java-aispeech/src/main/java/me/chanjar/weixin/aispeech/util/WxAispeechSignUtil.java","lineNumber":55,"sourceCode":"      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  }\n\n  private static String defaultString(String value) {\n    return value == null ? \"\" : value;\n  }\n\n  private static String bytesToHex(byte[] bytes) {\n    StringBuilder builder = new StringBuilder(bytes.length * 2);\n    for (byte b : bytes) {\n      builder.append(String.format(\"%02x\", b));\n    }\n    return builder.toString();\n  }","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/binarywang/WxJava/blob/1c43293a3c2c9d7e91304b6d037fb017f680d0c6/weixin-java-aispeech/src/main/java/me/chanjar/weixin/aispeech/util/WxAispeechSignUtil.java#L37-L73","documentation":"Thrown by `decryptAesCbcFromBase64` when AES/CBC decryption fails (GeneralSecurityException wrapped as IllegalStateException). Causes: the ciphertext is not valid base64, was tampered/truncated, padding is wrong, or the key does not match the one used for encryption (IV is derived from the key's first 16 bytes).","triggerScenarios":"Passing a wrong aesKey for the given ciphertext; corrupted/truncated base64 ciphertext; ciphertext from a different key session; bad padding from an incomplete payload.","commonSituations":"Key mismatch after rotation; copy-paste truncation of the ciphertext; transport layer corrupting the base64 string.","solutions":["Confirm the aesKey is the exact one used to encrypt this payload.","Ensure the ciphertext base64 is intact (no truncation, no embedded whitespace).","Check the wrapped cause: BadPaddingException usually means wrong key or tampered data.","If payloads are URL-transmitted, verify base64 URL-safety/encoding alignment."],"exampleFix":"// before\nString p = WxAispeechSignUtil.decryptAesCbcFromBase64(cipherText, wrongKey);  // throws\n// after\nString p = WxAispeechSignUtil.decryptAesCbcFromBase64(cipherText.trim(), correctKey);","handlingStrategy":"try-catch","validationCode":"// Validate inputs before decrypting\nif (StringUtils.isBlank(cipherTextBase64) || StringUtils.isBlank(aesKey)) {\n    throw new IllegalArgumentException(\"ciphertext and aesKey are required\");\n}\nbyte[] keyBytes = java.util.Base64.getDecoder().decode(aesKey.trim() + \"=\");\nif (keyBytes.length < 16) {\n    throw new IllegalArgumentException(\"AES key too short for IV derivation\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    String plain = WxAispeechSignUtil.decryptAesCbcFromBase64(cipherTextBase64, aesKey);\n} catch (IllegalStateException e) {\n    // BadPaddingException => wrong key or tampered/truncated ciphertext\n    log.error(\"AES decrypt failed; check key match and ciphertext integrity\", e.getCause());\n    throw e;\n}","preventionTips":["Use the exact key that encrypted the payload.","Preserve ciphertext base64 verbatim (no truncation/whitespace).","Inspect the wrapped cause to distinguish wrong-key vs corruption."],"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"}