{"record":{"id":"43876e84c9e7bd24","repo":"JeffreySu/WeiXinMPSDK","slug":"encodingaeskey-43","errorCode":null,"errorMessage":"EncodingAESKey 必须为 43 个字符。","messagePattern":"EncodingAESKey 必须为 43 个字符。","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.Work/Senparc.Weixin.Work/Entities/Request/Event/RequestMessageEvent_MiniProgramPay.cs","lineNumber":72,"sourceCode":"        public MiniProgramPayNotificationResource resource { get; set; }\n\n        /// <summary>通知摘要。</summary>\n        public string summary { get; set; }\n\n        /// <summary>\n        /// 使用“对外收款”应用回调配置中的 EncodingAESKey 解密业务资源。\n        /// .NET Framework 与 netstandard2.0 不提供平台 AES-GCM 实现，将抛出\n        /// <see cref=\"PlatformNotSupportedException\"/>；这些目标仍可接收完整加密通知模型。\n        /// </summary>\n        public string DecryptResource(string encodingAesKey)\n        {\n#if NET462 || NETSTANDARD2_0\n            throw new PlatformNotSupportedException(\n                \"当前目标框架不提供 AES-GCM。请在 netstandard2.1、netcoreapp3.1 或更新目标中解密通知资源。\");\n#else\n            if (string.IsNullOrEmpty(encodingAesKey) || encodingAesKey.Length != 43)\n            {\n                throw new ArgumentException(\"EncodingAESKey 必须为 43 个字符。\", nameof(encodingAesKey));\n            }\n\n            if (resource == null)\n            {\n                throw new InvalidOperationException(\"通知中不包含 resource 节点。\");\n            }\n\n            if (!string.Equals(resource.algorithm, \"AEAD_AES_256_GCM\", StringComparison.OrdinalIgnoreCase))\n            {\n                throw new NotSupportedException($\"不支持的通知资源加密算法：{resource.algorithm}\");\n            }\n\n            var key = Convert.FromBase64String(encodingAesKey + \"=\");\n            var encrypted = Convert.FromBase64String(resource.ciphertext);\n            const int tagSize = 16;\n            if (encrypted.Length <= tagSize)\n            {\n                throw new CryptographicException(\"通知资源密文长度无效。\");","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.Work/Senparc.Weixin.Work/Entities/Request/Event/RequestMessageEvent_MiniProgramPay.cs#L54-L90","documentation":"WeChat Work's EncodingAESKey is exactly 43 Base64 characters (decoding to a 32-byte AES key; the code appends '=' before decoding). DecryptResource validates this before decrypting the notification resource and throws ArgumentException when the key is null, empty, or the wrong length.","triggerScenarios":"Calling DecryptResource with a null/empty key, a truncated key copied from the WeChat Work admin console, or a key with whitespace/newline included.","commonSituations":"Misconfigured callback credentials: pasting the EncodingAESKey without the final characters, confusing EncodingAESKey with Token, or storing the key in config with trailing whitespace.","solutions":["Verify the EncodingAESKey from the WeChat Work admin console is exactly 43 characters and trim surrounding whitespace before passing it","Check the configuration source (appsettings/env var) actually contains the AES key, not the Token or other credential","Log the key length (not the key) at the call site to confirm what is being passed"],"exampleFix":"// before\nstring result = message.DecryptResource(aesKey);\n// after\nstring key = config.EncodingAesKey?.Trim();\nif (string.IsNullOrEmpty(key) || key.Length != 43)\n    throw new InvalidOperationException($\"EncodingAESKey length is {key?.Length ?? 0}, expected 43\");\nstring result = message.DecryptResource(key);","handlingStrategy":"validation","validationCode":"var key = config.EncodingAesKey?.Trim();\nif (string.IsNullOrEmpty(key) || key.Length != 43)\n    throw new InvalidOperationException($\"EncodingAESKey must be 43 chars, got {key?.Length ?? 0}\");","typeGuard":"static bool IsValidEncodingAesKey(string key) =>\n    !string.IsNullOrEmpty(key) && key.Length == 43 && Convert.TryFromBase64String(key + \"=\", new byte[32], out _);","tryCatchPattern":"try { var plain = msg.DecryptResource(aesKey); }\ncatch (ArgumentException ex) when (ex.ParamName == \"encodingAesKey\") { log.Error(\"Invalid EncodingAESKey length\"); throw; }","preventionTips":["Copy the EncodingAESKey exactly from the WeChat Work console and trim whitespace/newlines","Do not confuse EncodingAESKey with Token or CorpSecret","Add a startup config validation that checks key length = 43 and decodes to 32 bytes"],"tags":["cryptography","argument-validation","config"],"backgroundTag":"missing-required-config-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"}