diff --git a/JWT/JWT.cs b/JWT/JWT.cs index 264da0f68..87128cbe0 100644 --- a/JWT/JWT.cs +++ b/JWT/JWT.cs @@ -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>(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; @@ -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) + /// + /// Given the JWT, verifies it. + /// + /// >An arbitrary payload (already serialized to JSON). + /// Decoded body + /// Decoded signature + /// The signature is invalid. + /// The token has expired. + public static void Verify(string payloadJson, string decodedCrypto, string decodedSignature) { if (decodedCrypto != decodedSignature) { @@ -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>(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."); + } + } } } \ No newline at end of file