【问题标题】:C# Constructing a JWT token manually not workingC#手动构建JWT令牌不起作用
【发布时间】:2016-07-08 03:42:23
【问题描述】:

我正在尝试通过构建三个组件然后将它们组合来手动构建 JWT 令牌。据此:https://jwt.io/ 这个令牌分为三个部分; JWT 标头、有效负载和签名。以下代码似乎成功生成了前两个。但签名不正确:

public async Task<string> GetJWTToken(string user)
{

    var now = DateTime.UtcNow;
    //constructing part 1: header.Encode()
    JwtHeader jwtHeader = new JwtHeader();
    jwtHeader.Add("alg", JwtAlgorithms.HMAC_SHA512);
    var partOne = jwtHeader.Base64UrlEncode();

    //constructing part 2: payload.Encode  
    JwtPayload payload = new JwtPayload();
    payload.Add("sub", user);
    payload.Add("nbf",ConvertToUnixTimestamp(now.AddMinutes(-10)));
    var partTwo = payload.Base64UrlEncode();

    //constructing part 3: HS512(part1 + "." + part2, key)
    var tobeHashed = partOne + "." + partTwo;
    var sha = new HMACSHA512(Encoding.UTF8.GetBytes(ConfigurationHelper.AppSettings("JWTOfferKey")));
    var hashedByteArray = sha.ComputeHash(Encoding.UTF8.GetBytes(tobeHashed));
    StringBuilder partThree = new StringBuilder();

    foreach (var hashedByte in hashedByteArray)
    {
        partThree.Append(hashedByte.ToString("X2"));
    }

    //token = part1 + "." + part2 + "." + part3
    var tokenString = partOne + "." + partTwo + "." + Base64Encode(partThree.ToString());

    return tokenString;
}

public static double ConvertToUnixTimestamp(DateTime date)
{
    DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
    TimeSpan diff = date.ToUniversalTime() - origin;
    return Math.Floor(diff.TotalSeconds);
}

public static string Base64Encode(string plainText)
{
    var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
    return System.Convert.ToBase64String(plainTextBytes);
}

有人知道最后一部分的构造有什么问题吗?

【问题讨论】:

    标签: c# token jwt


    【解决方案1】:

    最后一部分的构造有什么问题?

    需要对签名哈希值进行base64UrlEncode

    public Task<string> GetJWTToken(string user) {
    
        //...other code removed for brevity
    
        //constructing part 3: HS512(part1 + "." + part2, key)
        var tobeHashed = string.Join(".", partOne, partTwo);
        var sha = new HMACSHA512(Encoding.UTF8.GetBytes(ConfigurationHelper.AppSettings("JWTOfferKey")));
        var hashedByteArray = sha.ComputeHash(Encoding.UTF8.GetBytes(tobeHashed));
    
        //You need to base64UrlEncode the signature hash value
        var partThree = Base64UrlEncode(hashedByteArray);
    
        //Now construct the token
        var tokenString = string.Join(".", tobeHashed, partThree);
    
        //await was not used so no need for `async` keyword. Just return task
        return Task.FromResult(tokenString);
    }
    
    // from JWT spec
    private static string Base64UrlEncode(byte[] input) {
        var output = Convert.ToBase64String(input);
        output = output.Split('=')[0]; // Remove any trailing '='s
        output = output.Replace('+', '-'); // 62nd char of encoding
        output = output.Replace('/', '_'); // 63rd char of encoding
        return output;
    }
    

    【讨论】:

      猜你喜欢
      • 2018-07-27
      • 2017-07-09
      • 2016-04-30
      • 2017-06-02
      • 2021-09-17
      • 2021-12-24
      • 1970-01-01
      • 2017-03-30
      • 2020-06-13
      相关资源
      最近更新 更多