2016-03-21 17 views
1

3つのコンポーネントをビルドして組み合わせることで、JWTトークンを手動で構築しようとしています。これによると:https://jwt.io/このトークンには3つの部分があります。 JWTヘッダ、ペイロード、および署名を含む。次のコードは、最初の2つを正常に生成するようです。署名が正しくない:C#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); 
} 

最後の部分の構成が間違っていることを知っている人はいますか?

答えて

1

最後の部分の構造は何ですか?あなたが署名ハッシュ値

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; 
} 
をbase64UrlEncodeする必要が

関連する問題