{"record":{"id":"3c3d69f79b5937c4","repo":"JeffreySu/WeiXinMPSDK","slug":"invalid-hex-length-for-uncompressed-ec-public-key","errorCode":null,"errorMessage":"Invalid hex length for uncompressed EC public key","messagePattern":"Invalid hex length for uncompressed EC public key","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Helpers/SMPemHelper.cs","lineNumber":55,"sourceCode":"\n\n        /// <summary>\n        /// 加载椭圆公钥参数\n        /// </summary>\n        /// <param name=\"publicKey\">PKCS#8 公钥字节数组。</param>\n        /// <returns></returns>\n        public static ECPublicKeyParameters LoadPublicKeyToParameters(byte[] publicKeyBytes)\n        {\n            //使用 X509Certificate2 证书\n            string hex;\n            using (var x509 = new X509Certificate2(publicKeyBytes))\n            {\n                hex = x509.GetPublicKeyString();\n            }\n            // 假设hex字符串是不带前缀的未压缩公钥（65字节：1字节0x04 + 32字节X坐标 + 32字节Y坐标）  \n            if (hex.Length != 130) // 04 + 2 * 32 * 2 (hex字符)  \n            {\n                throw new ArgumentException(\"Invalid hex length for uncompressed EC public key\");\n            }\n\n            // 去除可能的\"04\"前缀（如果是未压缩格式）  \n            if (hex.StartsWith(\"04\", StringComparison.OrdinalIgnoreCase))\n            {\n                hex = hex.Substring(2);\n            }\n\n            // 将十六进制字符串转换为字节数组  \n            byte[] keyBytes = Hex.Decode(hex);\n\n            // 分离X和Y坐标  \n            byte[] xBytes = new byte[32];\n            byte[] yBytes = new byte[32];\n            Array.Copy(keyBytes, 0, xBytes, 0, 32);\n            Array.Copy(keyBytes, 32, yBytes, 0, 32);\n\n            // 获取椭圆曲线参数  ","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Helpers/SMPemHelper.cs#L37-L73","documentation":"SMPemHelper.LoadPublicKeyToParameters expects the certificate's public key as an uncompressed EC point hex string of exactly 130 chars (0x04 prefix + 32-byte X + 32-byte Y). If the hex length differs, it throws ArgumentException because the key material can't be interpreted as an SM2 public key.","triggerScenarios":"Loading a certificate whose GetPublicKeyString() returns a DER/SubjectPublicKeyInfo-encoded key (longer hex) or a compressed point (66 chars) — e.g. an RSA cert or a non-uncompressed EC cert — into LoadPublicKeyToParameters.","commonSituations":"Using a standard WeChat Pay platform certificate (RSA) instead of an SM2/EC certificate, or a PEM exported in compressed-point format.","solutions":["Use a certificate containing an uncompressed 65-byte EC public key (04 + X + Y).","Pre-extract the 65-byte uncompressed point and pass a 130-char hex string instead of the raw cert output.","Convert the key: parse the SPKI, take the EC point, and normalize it to uncompressed form before calling."],"exampleFix":"// before\nvar hex = x509.GetPublicKeyString(); // SPKI-encoded, length != 130\nvar p = helper.LoadPublicKeyToParameters(hex);\n// after\nvar ecPoint = GetUncompressedEcPointHex(x509); // 65-byte point -> 130 hex chars\nvar p = helper.LoadPublicKeyToParameters(ecPoint);","handlingStrategy":"validation","validationCode":"bool IsValidUncompressedEcHex(string hex) =>\n    !string.IsNullOrEmpty(hex) && hex.Length == 130 &&\n    (hex.StartsWith(\"04\") || hex.StartsWith(\"06\") || hex.StartsWith(\"07\"));","typeGuard":null,"tryCatchPattern":"try { var p = SMPemHelper.LoadPublicKeyToParameters(hex); }\ncatch (ArgumentException ex) { logger.Error(ex, \"EC 公钥格式无效，需 65 字节未压缩格式\"); }","preventionTips":["Convert keys to uncompressed 65-byte format before loading","Don't feed RSA certs into SM2 helpers","Unit-test key loading with representative certs from your environment"],"tags":["cryptography","ec-public-key","sm2","argument"],"backgroundTag":"invalid-argument-format","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"}