{"record":{"id":"9c50db24ecea03cc","repo":"JeffreySu/WeiXinMPSDK","slug":"sessionkey-02","errorCode":null,"errorMessage":"SessionKey无效（02）","messagePattern":"SessionKey无效（02）","errorType":"exception","errorClass":"WxOpenException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen/Senparc.Weixin.WxOpen/Helpers/EncryptHelper.cs","lineNumber":116,"sourceCode":"        /// <summary>\n        /// 比较签名是否正确\n        /// </summary>\n        /// <param name=\"sessionId\"></param>\n        /// <param name=\"rawData\"></param>\n        /// <param name=\"compareSignature\"></param>\n        /// <exception cref=\"WxOpenException\">当SessionId或SessionKey无效时抛出异常</exception>\n        /// <returns></returns>\n        public static bool CheckSignature(string sessionId, string rawData, string compareSignature)\n        {\n            var sessionBag = SessionContainer.GetSession(sessionId);\n            if (sessionBag == null)\n            {\n                throw new WxOpenException(\"SessionId无效（01）\");\n            }\n\n            if (string.IsNullOrEmpty(sessionBag.SessionKey))\n            {\n                throw new WxOpenException(\"SessionKey无效（02）\");\n            }\n\n            var signature = GetSignature(rawData, sessionBag.SessionKey);\n            return signature == compareSignature;\n        }\n\n        #endregion\n\n        #region 解密\n\n        #region 私有方法\n\n        private static byte[] AES_Decrypt(String Input, byte[] Iv, byte[] Key, int keySize = 128)\n        {\n#if NET462\n            RijndaelManaged aes = new RijndaelManaged();\n#else\n            SymmetricAlgorithm aes = Aes.Create();","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen/Senparc.Weixin.WxOpen/Helpers/EncryptHelper.cs#L98-L134","documentation":"Thrown by EncryptHelper.CheckSignature when the session exists but its SessionKey is null or empty. CheckSignature computes HMAC/SHA1 of rawData with the SessionKey, so verification is impossible without one. Usually means the session record was created without a valid SessionKey from the wx jscode2session exchange.","triggerScenarios":"Calling CheckSignature with a sessionId whose SessionContainer entry has an empty SessionKey — e.g. session stored from a failed/short-circuited js2session call, or session key explicitly cleared.","commonSituations":"Custom code inserting session bags manually without a SessionKey; wx jscode2session returned an error (invalid js_code) but the session was still cached; cache entries partially deserialized/trimmed.","solutions":["Verify the js2session exchange succeeded (check errcode) and that SessionKey was stored in the bag before responding to the client","Re-run the login flow to regenerate a session with a valid SessionKey","Validate SessionKey presence on the server before handing out the sessionId","Catch WxOpenException (02) and prompt re-authentication"],"exampleFix":"// before — caching session even when js2session failed\nawait SessionContainer.AddSessionAsync(sessionId, appId, openId, sessionKey: result.session_key ?? \"\");\n// after\nif (string.IsNullOrEmpty(result.session_key)) throw new WxOpenException(\"js2session failed: \" + result.errcode);\nawait SessionContainer.AddSessionAsync(sessionId, appId, openId, result.session_key);","handlingStrategy":"validation","validationCode":"var bag = SessionContainer.GetSession(sessionId);\nif (bag == null || string.IsNullOrEmpty(bag.SessionKey)) {\n    return ForceRelogin(); // cannot verify signature without SessionKey\n}","typeGuard":"bool HasValidSessionKey(SessionBag bag) => bag != null && !string.IsNullOrEmpty(bag.SessionKey);","tryCatchPattern":"try {\n    var ok = EncryptHelper.CheckSignature(sessionId, rawData, compareSignature);\n} catch (WxOpenException ex) when (ex.Message.Contains(\"SessionKey无效\")) {\n    return Unauthorized(\"session missing SessionKey, re-authenticate\");\n}","preventionTips":["Only cache session bags after jscode2session returns a non-empty session_key","Check errcode on the jscode2session response before storing the session","Never construct session bags manually without a SessionKey","Log jscode2session failures so broken sessions are caught at login time"],"tags":["weixin","wxopen","session","sessionkey","signature"],"backgroundTag":"empty-required-field","analyzedSha":"be573f6f94bdbf718dd5f6cdecb137fbc7ff651e","analyzedAt":"2026-09-12T10:01:50.733Z","contentChangedAt":"2026-09-12T10:01:50.733Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}