2016-03-21 13 views
1

Ich versuche, ein JWT-Token manuell zu erstellen, indem ich die drei Komponenten aufbaue und sie dann kombiniere. Demnach: https://jwt.io/ gibt es drei Teile zu diesem Token; ein JWT-Header, eine Nutzlast und eine Signatur. Der folgende Code scheint die ersten beiden erfolgreich zu generieren. aber die Unterschrift ist nicht korrekt:C# Einen JWT-Token manuell erstellen funktioniert nicht

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); 
} 

Weiß jemand, was mit der Konstruktion des letzten Teils falsch ist?

Antwort

1

Was stimmt nicht mit der Konstruktion des letzten Teils?

Sie benötigen die Unterschrift Hash-Wert

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