You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ECDSA P512公钥验证JWT时抛出System.PlatformNotSupportedException

解决.NET Framework 4.8下ECDSA NIST P-512验证JWT的PlatformNotSupportedException问题

问题分析

你遇到的PlatformNotSupportedException主要源于两个核心问题:

  1. 手动解析PEM公钥的X/Y坐标有误:直接截取字节数组的方式没有精准匹配nistP521公钥的结构,导致导入时参数错误。
  2. .NET Framework 4.8原生ECDsa对nistP521的导入兼容性问题:Windows CNG(下一代加密技术)处理nistP521密钥时,需要更严谨的导入逻辑。
    另外,代码中ValidIssuer设置为"SMA_iOS",但JWT payload中的iss字段是"SMA_Android",这会导致后续Issuer验证失败,必须同步修正。

解决方案一:使用BouncyCastle库解析PEM公钥(推荐)

BouncyCastle库能可靠解析各类密钥格式,避免手动处理字节的出错风险。

步骤:

  1. 安装BouncyCastle NuGet包:
    Install-Package BouncyCastle
    
  2. 修改代码如下:
    using Microsoft.IdentityModel.Tokens;
    using Org.BouncyCastle.Crypto;
    using Org.BouncyCastle.Crypto.Parameters;
    using Org.BouncyCastle.OpenSsl;
    using Org.BouncyCastle.Security;
    using System;
    using System.IdentityModel.Tokens.Jwt;
    using System.Security.Claims;
    using System.Security.Cryptography;
    using System.IO;
    
    namespace ConsoleApp3
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                string token = @"eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzUxMiJ9.eyJhdWQiOiJPUkNBIiwiYWNjZXNzUmlnaHRJZCI6IjE2ZDlmMGU3LWFmYzMtZWQxMS1hOGUwLTAwMjI0ODFlMGM4MSIsImlzcyI6IlNNQV9BbmRyb2lkIiwiZXhwIjoxNjgwMDg3MjcxLCJpYXQiOjE2ODAwMDA4NzQsImp0aSI6IjUyMjM1ZjZjLTAxZjUtNDRhMS04N2UxLTQwYTU3MWY4YWM3NCJ9.AM4kbafsnXxtVHvIEjZ0dt6Q7fI0xXY_zTmkrsiSrD4sfB2Uy-WRnjLLPTH9Jt_RQ9YuHnSalFcRxizqh8sZjYsaAU1cj3qzWnfx2JdM0McAVoufIDzK8V6LUmiNQoBtStAGy5-QQBgA7VaqG8wRtooeHoFlE6gNqi1cYAynveZIdA6m";
    
                try
                {
                    const string es512PublicKey = @"-----BEGIN PUBLIC KEY-----
    

MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQB7yWOe2Q7FiOtrNw10l+a8CDnmDug
1MUpuvW6SWuRicmK/fqM9gAqVLLNZx2AeniCSAW5kcvdT1AjAHi31RYK/aQA4Vdl
IqtDRCnEwDqwrRN+IYMC1zwDvyfPS6yhe91uynZ1rWZJpF8wC2in1x+GdQTrbYpX
i5p91BXzF3sPWuB1XzA=
-----END PUBLIC KEY-----";

// 使用BouncyCastle解析PEM公钥
               ECDsa ecdsa;
               using (var reader = new StringReader(es512PublicKey))
               {
                   var pemReader = new PemReader(reader);
                   var publicKeyParams = pemReader.ReadObject() as ECPublicKeyParameters;
                   var ecParams = DotNetUtilities.ToECParameters(publicKeyParams);
                   ecParams.Curve = ECCurve.NamedCurves.nistP521;
                   ecdsa = ECDsa.Create(ecParams);
               }

               JwtSecurityTokenHandler jwtHandler = new JwtSecurityTokenHandler();
               TokenValidationParameters validationParameters = new TokenValidationParameters
               {
                   ValidateIssuer = true,
                   ValidIssuer = "SMA_Android", // 修正为JWT中的实际Issuer
                   ValidateAudience = false,
                   ValidateLifetime = true,
                   IssuerSigningKey = new ECDsaSecurityKey(ecdsa)
               };

               ClaimsPrincipal claimsPrincipal = jwtHandler.ValidateToken(token, validationParameters, out var validatedToken);
               Console.WriteLine("Token验证成功!");
           }
           catch (Exception ex)
           {
               Console.WriteLine(ex.ToString());
           }
       }
   }

}

## 解决方案二:修正原生解析方式(无第三方依赖)
若不想使用第三方库,需确保正确解析公钥结构,并指定兼容的CNG提供器:
```cs
// 替换原有的ECDsa创建代码
string pemData = es512PublicKey
 .Replace("-----BEGIN PUBLIC KEY-----", "")
 .Replace("-----END PUBLIC KEY-----", "")
 .Replace("\n", "")
 .Replace("\r", "");

byte[] keyBytes = Convert.FromBase64String(pemData);

// nistP521公钥结构为:0x04 + 66字节X + 66字节Y,正确提取X/Y
byte[] x = new byte[66];
byte[] y = new byte[66];
Buffer.BlockCopy(keyBytes, 1, x, 0, 66);
Buffer.BlockCopy(keyBytes, 67, y, 0, 66);

// 使用ECCng并指定支持nistP521的CNG提供器
var ecParams = new ECParameters
{
 Curve = ECCurve.NamedCurves.nistP521,
 Q = new ECPoint { X = x, Y = y }
};

ECDsaCng ecdsa = new ECDsaCng();
ecdsa.ImportParameters(ecParams);

关键注意事项

  • Issuer匹配:ValidIssuer必须与JWT payload中的iss字段完全一致,否则验证会直接失败。
  • 密钥格式:确保PEM公钥是标准的SubjectPublicKeyInfo格式(BEGIN PUBLIC KEY),而非PKCS#8或其他私有格式。

内容的提问来源于stack exchange,提问作者Kunal Mukherjee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 05:27:38