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
- 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.
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
- 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
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)