} // End Function Decode /// <summary> /// Given a JWT, decode it and return the JSON payload. /// </summary> /// <param name="token">The JWT.</param> /// <param name="key">The key bytes that were used to sign the JWT.</param> /// <param name="verifySignature">Whether to verify the signature (default is true).</param> /// <returns>A string containing the JSON payload.</returns> /// <exception cref="SignatureVerificationException">Thrown if the verify parameter was true and the signature was NOT valid or if the JWT was signed with an unsupported algorithm.</exception> /// <exception cref="TokenExpiredException">Thrown if the verify parameter was true and the token has an expired exp claim.</exception> public static string Decode(string token, JwtKey key, bool verifySignature = true) { string[] parts = token.Split('.'); if (parts.Length != 3) { throw new System.ArgumentException("Token must consist from 3 delimited by dot parts"); } // End if (parts.Length != 3) string header = parts[0]; string payload = parts[1]; byte[] crypto = Base64UrlDecode(parts[2]); string headerJson = System.Text.Encoding.UTF8.GetString(Base64UrlDecode(header)); string payloadJson = System.Text.Encoding.UTF8.GetString(Base64UrlDecode(payload)); System.Collections.Generic.Dictionary <string, object> headerData = JsonSerializer.Deserialize <System.Collections.Generic.Dictionary <string, object> >(headerJson); if (verifySignature) { byte[] bytesToSign = System.Text.Encoding.UTF8.GetBytes(string.Concat(header, ".", payload)); string algorithm = (string)headerData["alg"]; byte[] signature = HashAlgorithms[GetHashAlgorithm(algorithm)](key, bytesToSign); string decodedCrypto = System.Convert.ToBase64String(crypto); string decodedSignature = System.Convert.ToBase64String(signature); Verify(decodedCrypto, decodedSignature, payloadJson); } // End if (verify) return(payloadJson); } // End Function Decode
private static JwtKey[] GetKeys(X509Certificate2[] certs) { var keys = new List <JwtKey>(); foreach (var cert in certs) { var rsa = cert.GetRSAPublicKey(); if (rsa == null) { throw new IdentityProviderException("X509 must be RSA"); } var parameters = rsa.ExportParameters(false); var publicKey = cert.Export(X509ContentType.Cert); var certString = Convert.ToBase64String(publicKey); var key = new JwtKey() { KeyID = cert.Thumbprint, Use = "sig", KeyType = "RSA", X509Thumbprint = cert.Thumbprint, //same as KeyID Exponent = Base64UrlEncoder.ToBase64String(parameters.Exponent), Modulus = Base64UrlEncoder.ToBase64String(parameters.Modulus), X509Certificates = new string[] { certString } }; keys.Add(key); } return(keys.ToArray()); }
public void ReCreateJWT() { byte[] key = new byte[128]; new Random().NextBytes(key); string keyStr = Convert.ToBase64String(key); JwtKey.Value = keyStr; JwtKey.Save(); }
public static SecurityKey TryConvertPemToSecurityKey(this JwtKey jwtSecurityKey) { if (jwtSecurityKey.Key.Contains("PRIVATE")) { return(LoadPrivateKey(jwtSecurityKey.Key)); } if (jwtSecurityKey.Key.Contains("PUBLIC")) { return(LoadPublicKey(jwtSecurityKey.Key)); } throw new ConvertPemException( $"Unable to determine whether key {jwtSecurityKey.Algorithm} is private or public: {jwtSecurityKey.Key}"); }
} // End Function DecodeToObject /// <summary> /// Given a JWT, decode it and return the payload as an object (by deserializing it with System.Web.Script.Serialization.JavaScriptSerializer). /// </summary> /// <typeparam name="T">The <see cref="System.Type"/> to return</typeparam> /// <param name="token">The JWT.</param> /// <param name="key">The key that was used to sign the JWT.</param> /// <param name="verify">Whether to verify the signature (default is true).</param> /// <returns>An object representing the payload.</returns> /// <exception cref="SignatureVerificationException">Thrown if the verify parameter was true and the signature was NOT valid or if the JWT was signed with an unsupported algorithm.</exception> /// <exception cref="TokenExpiredException">Thrown if the verify parameter was true and the token has an expired exp claim.</exception> public static T DecodeToObject <T>(string token, JwtKey key, bool verify = true) { string payloadJson = Decode(token, key, verify); return(JsonSerializer.Deserialize <T>(payloadJson)); } // End Function DecodeToObject
} // End Function DecodeToObject /// <summary> /// Given a JWT, decode it and return the payload as an object (by deserializing it with System.Web.Script.Serialization.JavaScriptSerializer). /// </summary> /// <param name="token">The JWT.</param> /// <param name="key">The key that was used to sign the JWT.</param> /// <param name="verify">Whether to verify the signature (default is true).</param> /// <returns>An object representing the payload.</returns> /// <exception cref="SignatureVerificationException">Thrown if the verify parameter was true and the signature was NOT valid or if the JWT was signed with an unsupported algorithm.</exception> /// <exception cref="TokenExpiredException">Thrown if the verify parameter was true and the token has an expired exp claim.</exception> public static object DecodeToObject(string token, JwtKey key, bool verify = true) { string payloadJson = Decode(token, key, verify); return(JsonSerializer.Deserialize <System.Collections.Generic.Dictionary <string, object> >(payloadJson)); } // End Function DecodeToObject
} // End Function Encode /// <summary> /// Creates a JWT given a header, a payload, the signing key, and the algorithm to use. /// </summary> /// <param name="extraHeaders">An arbitrary set of extra headers. Will be augmented with the standard "typ" and "alg" headers.</param> /// <param name="payload">An arbitrary payload (must be serializable to JSON via System.Web.Script.Serialization.JavaScriptSerializer).</param> /// <param name="key">The key bytes used to sign the token.</param> /// <param name="algorithm">The hash algorithm to use.</param> /// <returns>The generated JWT.</returns> public static string Encode(System.Collections.Generic.IDictionary <string, object> extraHeaders, object payload, JwtKey key, JwtHashAlgorithm algorithm) { string retVal = null; System.Collections.Generic.Dictionary <string, object> header = new System.Collections.Generic.Dictionary <string, object>(extraHeaders) { { "typ", "JWT" }, { "alg", algorithm.ToString() } }; byte[] headerBytes = System.Text.Encoding.UTF8.GetBytes(JsonSerializer.Serialize(header)); byte[] payloadBytes = System.Text.Encoding.UTF8.GetBytes(JsonSerializer.Serialize(payload)); System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.Append(Base64UrlEncode(headerBytes)); sb.Append("."); sb.Append(Base64UrlEncode(payloadBytes)); byte[] bytesToSign = System.Text.Encoding.UTF8.GetBytes(sb.ToString()); byte[] signature = HashAlgorithms[algorithm](key, bytesToSign); sb.Append("."); sb.Append(Base64UrlEncode(signature)); retVal = sb.ToString(); sb.Length = 0; sb = null; return(retVal); } // End Function Encode
} // End Function Encode /// <summary> /// Creates a JWT given a header, a payload, the signing key, and the algorithm to use. /// </summary> /// <param name="payload">An arbitrary payload (must be serializable to JSON via System.Web.Script.Serialization.JavaScriptSerializer).</param> /// <param name="key">The key bytes used to sign the token.</param> /// <param name="algorithm">The hash algorithm to use.</param> /// <returns>The generated JWT.</returns> public static string Encode(object payload, JwtKey key, JwtHashAlgorithm algorithm) { return(Encode(new System.Collections.Generic.Dictionary <string, object>(), payload, key, algorithm)); }