Skip to content

Commit

Permalink
Making Verify() public (#52)
Browse files Browse the repository at this point in the history
* Refactoring Decode(), extracting private Verify()
* Making Verify() public, reodering parameters, adding xml doc
  • Loading branch information
abatishchev authored Sep 15, 2016
1 parent d848369 commit 87700ef
Showing 1 changed file with 39 additions and 26 deletions.
65 changes: 39 additions & 26 deletions JWT/JWT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,25 +128,13 @@ public static string Decode(string token, byte[] key, bool verify = true)
{
throw new ArgumentException("Token must consist from 3 delimited by dot parts");
}
var header = parts[0];
var payload = parts[1];
var crypto = Base64UrlDecode(parts[2]);

var headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header));
var payload = parts[1];
var payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(payload));

var headerData = JsonSerializer.Deserialize<Dictionary<string, object>>(headerJson);

if (verify)
{
var bytesToSign = Encoding.UTF8.GetBytes(string.Concat(header, ".", payload));
var algorithm = (string)headerData["alg"];

var signature = HashAlgorithms[GetHashAlgorithm(algorithm)](key, bytesToSign);
var decodedCrypto = Convert.ToBase64String(crypto);
var decodedSignature = Convert.ToBase64String(signature);

Verify(decodedCrypto, decodedSignature, payloadJson);
Verify(payload, payloadJson, parts, key);
}

return payloadJson;
Expand Down Expand Up @@ -239,18 +227,15 @@ public static byte[] Base64UrlDecode(string input)
return converted;
}

private static JwtHashAlgorithm GetHashAlgorithm(string algorithm)
{
switch (algorithm)
{
case "HS256": return JwtHashAlgorithm.HS256;
case "HS384": return JwtHashAlgorithm.HS384;
case "HS512": return JwtHashAlgorithm.HS512;
default: throw new SignatureVerificationException("Algorithm not supported.");
}
}

private static void Verify(string decodedCrypto, string decodedSignature, string payloadJson)
/// <summary>
/// Given the JWT, verifies it.
/// </summary>
/// <param name="payloadJson">>An arbitrary payload (already serialized to JSON).</param>
/// <param name="decodedCrypto">Decoded body</param>
/// <param name="decodedSignature">Decoded signature</param>
/// <exception cref="SignatureVerificationException">The signature is invalid.</exception>
/// <exception cref="TokenExpiredException">The token has expired.</exception>
public static void Verify(string payloadJson, string decodedCrypto, string decodedSignature)
{
if (decodedCrypto != decodedSignature)
{
Expand Down Expand Up @@ -279,5 +264,33 @@ private static void Verify(string decodedCrypto, string decodedSignature, string
throw new TokenExpiredException("Token has expired.");
}
}

private static void Verify(string payload, string payloadJson, string[] parts, byte[] key)
{
var crypto = Base64UrlDecode(parts[2]);
var decodedCrypto = Convert.ToBase64String(crypto);

var header = parts[0];
var headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header));
var headerData = JsonSerializer.Deserialize<Dictionary<string, object>>(headerJson);
var algorithm = (string)headerData["alg"];

var bytesToSign = Encoding.UTF8.GetBytes(string.Concat(header, ".", payload));
var signatureData = HashAlgorithms[GetHashAlgorithm(algorithm)](key, bytesToSign);
var decodedSignature = Convert.ToBase64String(signatureData);

Verify(payloadJson, decodedCrypto, decodedSignature);
}

private static JwtHashAlgorithm GetHashAlgorithm(string algorithm)
{
switch (algorithm)
{
case "HS256": return JwtHashAlgorithm.HS256;
case "HS384": return JwtHashAlgorithm.HS384;
case "HS512": return JwtHashAlgorithm.HS512;
default: throw new SignatureVerificationException("Algorithm not supported.");
}
}
}
}

0 comments on commit 87700ef

Please sign in to comment.