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

JWT Base64解码遇System.FormatException问题求助

JWT解码触发System.FormatException问题

错误详情

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

解码代码

// token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTExODcyODcsImlzcyI6IlRlc3QuY29tIiwiYXVkIjoiVGVzdC5jb20ifQ.pgzHJVC-iuvPaMuYzFNwPREFQsUVsLlKia11AM3ai1Y
string[] tokens = token.Split('.');

// first tokenPart = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 解码正常
// second tokenPart = eyJleHAiOjE3MTExODcyODcsImlzcyI6IlRlc3QuY29tIiwiYXVkIjoiVGVzdC5jb20ifQ 解码失败

foreach (string tokenPart in tokens) 
{
    string decodedString = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(tokenPart));
}

出错的Token片段

eyJleHAiOjE3MTExODQ3MDUsImlzcyI6IlRlc3QuY29tIiwiYXVkIjoiVGVzdC5jb20ifQ

该片段可正常解码为:

{"exp":1711179891,"iss":"Test.com","aud":"Test.com"}

JWT由以下服务端代码生成:

public string GenerateJSONWebToken(int userID, string key, string issuer)
{
    SymmetricSecurityKey securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
    SigningCredentials credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

    JwtSecurityToken token = new JwtSecurityToken(
        issuer,
        issuer, 
        null,
        expires: DateTime.Now.AddSeconds(10),
        signingCredentials: credentials);

    return new JwtSecurityTokenHandler().WriteToken(token);
}

解决方案

问题核心:JWT的Header和Payload采用Base64Url编码,而非标准Base64编码,两者差异如下:

  • Base64Url将+替换为-、/替换为_
  • Base64Url会省略末尾的填充字符=

直接用Convert.FromBase64String解码会因格式不匹配报错,需先将Base64Url转换为标准Base64格式。

手动修正编码的解码代码

string[] tokens = token.Split('.');

foreach (string tokenPart in tokens)
{
    if (string.IsNullOrEmpty(tokenPart)) continue;

    // 转换Base64Url到标准Base64
    string base64 = tokenPart
        .Replace('-', '+')
        .Replace('_', '/');
    
    // 补全填充字符
    switch (base64.Length % 4)
    {
        case 2: base64 += "=="; break;
        case 3: base64 += "="; break;
    }

    string decodedString = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(base64));
}

更可靠的方式:用JWT库直接解析

既然生成JWT用的是System.IdentityModel.Tokens.Jwt库,直接用同库解析更省心,无需手动处理编码:

var handler = new JwtSecurityTokenHandler();
JwtSecurityToken jwtToken = handler.ReadJwtToken(token);

// 直接获取Header和Payload
var headerData = jwtToken.Header;
var payloadData = jwtToken.Payload;

// 示例:序列化Payload输出
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(payloadData));

这种方式还支持后续的签名验证(若需要),避免手动处理编码的潜在问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 04:31:30