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

验证JWT签名时读取JWK文件n/e字段遇System.FormatException

问题分析与解决

问题背景

尝试通过服务器托管的JWK文件验证JWT签名,定义了Jwk模型并实现了验证逻辑,但在转换JWK的n和e字段时抛出System.FormatException,提示输入不是有效的Base64字符串。

代码与错误信息

Jwk模型

public class Jwk{
        [JsonProperty("alg")]
        public string Alg { get; set; }

        [JsonProperty("e")]
        public string E { get; set; }

        [JsonProperty("kty")]
        public string Kty { get; set; }

        [JsonProperty("n")]
        public string N { get; set; }

        [JsonProperty("use")]
        public string Use { get; set; }
}

验证方法

public TokenValidationParameters VerifyToken(Jwk jwk)
{
    // 此处抛出异常
    RSAParameters rsaParams = new RSAParameters
    {
        Modulus = Convert.FromBase64String(jwk.N),
        Exponent = Convert.FromBase64String(jwk.E),
        
    };

    using RSA rsa = RSA.Create();
    rsa.ImportParameters(rsaParams);

    var validationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new RsaSecurityKey(rsa)
    };

    return validationParameters;
}

错误信息

System.FormatException: 'The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.'

所用JWK数据

{ 
    "kty": "RSA", 
    "n": "qum6HexDv55WPr9iqoO-yOoqGRiFaF0Vx7YAigPYsLdyAgnmQRKxI81_XgJfH_f18mNO_j4GCVLIzvQYZGFw9cIs3b3kt9frxNssc24_Uh6zccvE2XWn9yr81OYu85OfL4mgA1WQPm-ZKIzvPq77ISY51PBSpK6FQkwuc9OhWDk",
    "e": "AQAB", 
    "alg": "RS256", 
    "use": "sig" 
} 

解决方法

问题核心是JWK中的n和e采用的是Base64URL编码,而非标准Base64编码,两者的差异如下:

  • Base64URL用-替代标准Base64的+
  • 用_替代/
  • 省略末尾的填充符=

需要先将Base64URL转换为标准Base64,再进行解析。实现转换方法:

private static byte[] Base64UrlDecode(string base64Url)
{
    // 替换特殊字符为标准Base64格式
    string base64 = base64Url.Replace('-', '+').Replace('_', '/');
    
    // 补充缺失的填充字符
    switch (base64.Length % 4)
    {
        case 2: base64 += "=="; break;
        case 3: base64 += "="; break;
    }
    
    return Convert.FromBase64String(base64);
}

修改验证方法,使用上述转换方法替代原有的Convert.FromBase64String,同时清理可能存在的换行符:

public TokenValidationParameters VerifyToken(Jwk jwk)
{
    // 清理反序列化时可能保留的换行符
    string cleanN = jwk.N.Replace("\n", "").Replace("\r", "");
    string cleanE = jwk.E.Replace("\n", "").Replace("\r", "");

    RSAParameters rsaParams = new RSAParameters
    {
        Modulus = Base64UrlDecode(cleanN),
        Exponent = Base64UrlDecode(cleanE),
    };

    using RSA rsa = RSA.Create();
    rsa.ImportParameters(rsaParams);

    var validationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new RsaSecurityKey(rsa)
    };

    return validationParameters;
}

内容的提问来源于stack exchange,提问作者rabner casandra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 01:58:14