Implementing JSON Web Tokens in .NET with a Base 64 URL Encoded key

Posted June 4, 2013

I wasn’t able to find any good technical examples of how to implement JSON Web Tokens (JWT) for .NET when the key is Base 64 URL encoded according to the JWT spec (http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-08#appendix-A.1, page 35).

John Sheehan’s JWT library on GitHub is a nice starting point, and works well when the key is ASCII encoded already, but it cannot be used without modification if the key is Base 64 URL Encoded.

Here’s the solution:

// URL Encode the string, according to
// http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-08#appendix-A.1, page 35
public string Base64UrlEncode(byte[] arg)
{
string s = Convert.ToBase64String(arg); // Regular base64 encoder
s = s.Split('=')[0]; // Remove any trailing '='s
s = s.Replace('+', '-'); // 62nd char of encoding
s = s.Replace('/', '_'); // 63rd char of encoding
return s;
}
public byte[] Base64UrlDecode(string arg)
{
string s = arg;
s = s.Replace('-', '+'); // 62nd char of encoding
s = s.Replace('_', '/'); // 63rd char of encoding
switch (s.Length % 4) // Pad with trailing '='s
{
case 0: break; // No pad chars in this case
case 2: s += "=="; break; // Two pad chars
case 3: s += "="; break; // One pad char
default: throw new System.Exception(
"Illegal base64url string!");
}
return Convert.FromBase64String(s); // Standard base64 decoder
}
// Implementation of http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-08,
// section A.1.1, JWS using HMAC SHA-256 (encoding), by J.T. Taylor, SecureVideo.com
public string GetAuthenticationToken(string base64UrlEncodedSecretKey, string userId)
{
// Prepare authentication token
// Get Unix-style expiration date
double unixSeconds = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
double expiry = unixSeconds + (2 * 24 * 60 * 60);
string jwsHeader = "{" +
""typ":"JWT"," +
""alg":"HS256"" +
"}";
byte[] jwsHeaderUtf8Bytes = Encoding.UTF8.GetBytes(jwsHeader);
string encodedJwsHeaderValue = Base64UrlEncode(jwsHeaderUtf8Bytes);
string payloadJson = "{" +
""sub":"" + userId + ""," +
""iss":"service-id"," +
""exp":" + expiry.ToString("0") +
"}";
byte[] jwsPayloadUtf8Bytes = Encoding.UTF8.GetBytes(payloadJson);
string encodedJwsPayloadValue = Base64UrlEncode(jwsPayloadUtf8Bytes);
string jwsSecuredInputValue = encodedJwsHeaderValue + "." + encodedJwsPayloadValue;
byte[] jwsSecuredInputAsciiBytes = Encoding.ASCII.GetBytes(jwsSecuredInputValue);
byte[] secretKeyBytes = Base64UrlDecode(base64UrlEncodedSecretKey);
var hmacSha256 = new HMACSHA256(secretKeyBytes);
byte[] signatureBytes = hmacSha256.ComputeHash(jwsSecuredInputAsciiBytes);
string encodedJwsSignatureValue = Base64UrlEncode(signatureBytes);
string jwt = jwsSecuredInputValue + "." + encodedJwsSignatureValue;
return jwt;
}

MOST RECENT

Why Consumers Love Telehealth

Keeping up with your health is everything, so why do so many patients have trouble doing this? Well it’s not just apathy or simple inconveniences. There are many reasons that can prevent a patient from either Seeking care when they need it Keeping up with their prescribed care Following through on annual check-ups What are […]

October 22, 2018

5 Ways Telehealth Benefits Your Practice

In today’s connected world, a majority of healthcare patients prefer easy access to physician services over in-person office visits. Whether a patient needs advice on a child’s fever, wants clarification on medication or presents with a condition that can be assessed and treated remotely, virtual visits offer on-demand care without the loss of time or the cost […]

October 16, 2018