JeffreySu/WeiXinMPSDK · error · ArgumentException

Invalid hex length for uncompressed EC public key

Error message

Invalid hex length for uncompressed EC public key

What it means

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.

Solutions

  1. Use a certificate containing an uncompressed 65-byte EC public key (04 + X + Y).
  2. Pre-extract the 65-byte uncompressed point and pass a 130-char hex string instead of the raw cert output.
  3. Convert the key: parse the SPKI, take the EC point, and normalize it to uncompressed form before calling.

Example fix

// before
var hex = x509.GetPublicKeyString(); // SPKI-encoded, length != 130
var p = helper.LoadPublicKeyToParameters(hex);
// after
var ecPoint = GetUncompressedEcPointHex(x509); // 65-byte point -> 130 hex chars
var p = helper.LoadPublicKeyToParameters(ecPoint);
Defensive patterns

Strategy: validation

Validate before calling

bool IsValidUncompressedEcHex(string hex) =>
    !string.IsNullOrEmpty(hex) && hex.Length == 130 &&
    (hex.StartsWith("04") || hex.StartsWith("06") || hex.StartsWith("07"));

Try / catch

try { var p = SMPemHelper.LoadPublicKeyToParameters(hex); }
catch (ArgumentException ex) { logger.Error(ex, "EC 公钥格式无效,需 65 字节未压缩格式"); }

Prevention

When it happens

Trigger: 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.

Common situations: Using a standard WeChat Pay platform certificate (RSA) instead of an SM2/EC certificate, or a PEM exported in compressed-point format.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12). Data as JSON: /api/errors/3c3d69f79b5937c4. Report an issue: GitHub.

Appendix: source

Thrown at src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Helpers/SMPemHelper.cs:55


        /// <summary>
        /// 加载椭圆公钥参数
        /// </summary>
        /// <param name="publicKey">PKCS#8 公钥字节数组。</param>
        /// <returns></returns>
        public static ECPublicKeyParameters LoadPublicKeyToParameters(byte[] publicKeyBytes)
        {
            //使用 X509Certificate2 证书
            string hex;
            using (var x509 = new X509Certificate2(publicKeyBytes))
            {
                hex = x509.GetPublicKeyString();
            }
            // 假设hex字符串是不带前缀的未压缩公钥(65字节:1字节0x04 + 32字节X坐标 + 32字节Y坐标)  
            if (hex.Length != 130) // 04 + 2 * 32 * 2 (hex字符)  
            {
                throw new ArgumentException("Invalid hex length for uncompressed EC public key");
            }

            // 去除可能的"04"前缀(如果是未压缩格式)  
            if (hex.StartsWith("04", StringComparison.OrdinalIgnoreCase))
            {
                hex = hex.Substring(2);
            }

            // 将十六进制字符串转换为字节数组  
            byte[] keyBytes = Hex.Decode(hex);

            // 分离X和Y坐标  
            byte[] xBytes = new byte[32];
            byte[] yBytes = new byte[32];
            Array.Copy(keyBytes, 0, xBytes, 0, 32);
            Array.Copy(keyBytes, 32, yBytes, 0, 32);

            // 获取椭圆曲线参数  

View on GitHub (pinned to be573f6f94)