{"record":{"id":"8d8aca577b300446","repo":"iflytek/astron-agent","slug":"40001-signature-validation-error","errorCode":"-40001","errorMessage":"Signature validation error","messagePattern":"Signature validation error","errorType":"error_code","errorClass":"AesException","httpStatus":null,"severity":"error","filePath":"console/backend/hub/src/main/java/com/iflytek/astron/console/hub/util/wechat/WXBizMsgCrypt.java","lineNumber":209,"sourceCode":"    }\n\n    /**\n     * Verify URL\n     *\n     * @param msgSignature Signature string\n     * @param timeStamp Timestamp\n     * @param nonce Random number\n     * @param echoStr Random string\n     * @return Decrypted echostr\n     * @throws AesException Execution failed, please check the error code and specific error message of\n     *         this exception\n     */\n    public String verifyUrl(String msgSignature, String timeStamp, String nonce, String echoStr)\n            throws AesException {\n        String signature = getSHA1(token, timeStamp, nonce, echoStr);\n\n        if (!signature.equals(msgSignature)) {\n            throw new AesException(AesException.ValidateSignatureError);\n        }\n\n        String result = decrypt(echoStr);\n        return result;\n    }\n\n    /**\n     * Decrypt message\n     *\n     * @param msgSignature Signature string\n     * @param timeStamp Timestamp\n     * @param nonce Random number\n     * @param postData Encrypted XML\n     * @return Decrypted XML\n     * @throws AesException Execution failed, please check the error code and specific error message of\n     *         this exception\n     */\n    public String decryptMsg(String msgSignature, String timeStamp, String nonce, String postData)","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/hub/src/main/java/com/iflytek/astron/console/hub/util/wechat/WXBizMsgCrypt.java#L191-L227","documentation":"WXBizMsgCrypt.verifyUrl computes the SHA-1 signature over (token, timestamp, nonce, echoStr) during WeChat server URL verification and compares it to the msgSignature sent by WeChat. When the two differ it throws AesException with code -40001 (ValidateSignatureError), meaning the callback request cannot be attributed to a sender holding the correct EncodingAESKey/token pair. This is the standard WeChat callback security check failing.","triggerScenarios":"Calling verifyUrl(msgSignature, timeStamp, nonce, echoStr) when the computed SHA1(token, timeStamp, nonce, echoStr) does not equal the msgSignature query parameter WeChat appended to the verification URL.","commonSituations":"Token in application config differs from the token configured in the WeChat Official Account backend; the timestamp/nonce/echoStr query params were not passed through unchanged (URL decoding issues, reordered params, proxied requests stripping query strings); a replayed or forged callback request; testing the endpoint manually without WeChat's signature params.","solutions":["Verify the token value used to construct WXBizMsgCrypt exactly matches the Token set in the WeChat MP admin console (whitespace/case included).","Confirm the controller passes the original msg_signature, timestamp, nonce and echostr query parameters verbatim to verifyUrl — check URL-decoding and any reverse-proxy rewrite rules.","Log the locally computed signature vs the incoming msgSignature to identify which input diverges.","Ensure you are responding to WeChat's GET verification (echostr) and not a POST message push with this code path."],"exampleFix":"// before\nString sig = getSHA1(myToken, ts, nonce, echoStr); // myToken differs from MP console\n// after\nString sig = getSHA1(tokenFromConfigMatchingWechatConsole, ts, nonce, echoStr);","handlingStrategy":"try-catch","validationCode":"if (msgSignature == null || timeStamp == null || nonce == null || echoStr == null) throw new IllegalArgumentException(\"missing WeChat verification params\");","typeGuard":null,"tryCatchPattern":"try { return crypto.verifyUrl(msgSignature, timestamp, nonce, echoStr); } catch (AesException e) { if (e.getCode() == -40001) { log.warn(\"signature mismatch\"); return ResponseEntity.status(403).body(\"signature invalid\"); } throw e; }","preventionTips":["Keep token config in sync with the WeChat MP console","Forward query params verbatim; check proxy rewrites","Log computed vs received signatures when debugging","Never hardcode a different token in test environments"],"tags":["wechat","signature-validation","callback","security"],"backgroundTag":"checksum-mismatch","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}