Advertisement
Guest User

Untitled

a guest
Apr 13th, 2012
2,513
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.70 KB | None | 0 0
  1. Is there a JSON Web Token (JWT) example in C#?
  2. public enum JwtHashAlgorithm
  3. {
  4. RS256,
  5. HS384,
  6. HS512
  7. }
  8.  
  9. public class JsonWebToken
  10. {
  11. private static Dictionary<JwtHashAlgorithm, Func<byte[], byte[], byte[]>> HashAlgorithms;
  12.  
  13. static JsonWebToken()
  14. {
  15. HashAlgorithms = new Dictionary<JwtHashAlgorithm, Func<byte[], byte[], byte[]>>
  16. {
  17. { JwtHashAlgorithm.RS256, (key, value) => { using (var sha = new HMACSHA256(key)) { return sha.ComputeHash(value); } } },
  18. { JwtHashAlgorithm.HS384, (key, value) => { using (var sha = new HMACSHA384(key)) { return sha.ComputeHash(value); } } },
  19. { JwtHashAlgorithm.HS512, (key, value) => { using (var sha = new HMACSHA512(key)) { return sha.ComputeHash(value); } } }
  20. };
  21. }
  22.  
  23. public static string Encode(object payload, string key, JwtHashAlgorithm algorithm)
  24. {
  25. return Encode(payload, Encoding.UTF8.GetBytes(key), algorithm);
  26. }
  27.  
  28. public static string Encode(object payload, byte[] keyBytes, JwtHashAlgorithm algorithm)
  29. {
  30. var segments = new List<string>();
  31. var header = new { alg = algorithm.ToString(), typ = "JWT" };
  32.  
  33. byte[] headerBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header, Formatting.None));
  34. byte[] payloadBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload, Formatting.None));
  35. //byte[] payloadBytes = Encoding.UTF8.GetBytes(@"{"iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com","scope":"https://www.googleapis.com/auth/prediction","aud":"https://accounts.google.com/o/oauth2/token","exp":1328554385,"iat":1328550785}");
  36.  
  37. segments.Add(Base64UrlEncode(headerBytes));
  38. segments.Add(Base64UrlEncode(payloadBytes));
  39.  
  40. var stringToSign = string.Join(".", segments.ToArray());
  41.  
  42. var bytesToSign = Encoding.UTF8.GetBytes(stringToSign);
  43.  
  44. byte[] signature = HashAlgorithms[algorithm](keyBytes, bytesToSign);
  45. segments.Add(Base64UrlEncode(signature));
  46.  
  47. return string.Join(".", segments.ToArray());
  48. }
  49.  
  50. public static string Decode(string token, string key)
  51. {
  52. return Decode(token, key, true);
  53. }
  54.  
  55. public static string Decode(string token, string key, bool verify)
  56. {
  57. var parts = token.Split('.');
  58. var header = parts[0];
  59. var payload = parts[1];
  60. byte[] crypto = Base64UrlDecode(parts[2]);
  61.  
  62. var headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header));
  63. var headerData = JObject.Parse(headerJson);
  64. var payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(payload));
  65. var payloadData = JObject.Parse(payloadJson);
  66.  
  67. if (verify)
  68. {
  69. var bytesToSign = Encoding.UTF8.GetBytes(string.Concat(header, ".", payload));
  70. var keyBytes = Encoding.UTF8.GetBytes(key);
  71. var algorithm = (string)headerData["alg"];
  72.  
  73. var signature = HashAlgorithms[GetHashAlgorithm(algorithm)](keyBytes, bytesToSign);
  74. var decodedCrypto = Convert.ToBase64String(crypto);
  75. var decodedSignature = Convert.ToBase64String(signature);
  76.  
  77. if (decodedCrypto != decodedSignature)
  78. {
  79. throw new ApplicationException(string.Format("Invalid signature. Expected {0} got {1}", decodedCrypto, decodedSignature));
  80. }
  81. }
  82.  
  83. return payloadData.ToString();
  84. }
  85.  
  86. private static JwtHashAlgorithm GetHashAlgorithm(string algorithm)
  87. {
  88. switch (algorithm)
  89. {
  90. case "RS256": return JwtHashAlgorithm.RS256;
  91. case "HS384": return JwtHashAlgorithm.HS384;
  92. case "HS512": return JwtHashAlgorithm.HS512;
  93. default: throw new InvalidOperationException("Algorithm not supported.");
  94. }
  95. }
  96.  
  97. // from JWT spec
  98. private static string Base64UrlEncode(byte[] input)
  99. {
  100. var output = Convert.ToBase64String(input);
  101. output = output.Split('=')[0]; // Remove any trailing '='s
  102. output = output.Replace('+', '-'); // 62nd char of encoding
  103. output = output.Replace('/', '_'); // 63rd char of encoding
  104. return output;
  105. }
  106.  
  107. // from JWT spec
  108. private static byte[] Base64UrlDecode(string input)
  109. {
  110. var output = input;
  111. output = output.Replace('-', '+'); // 62nd char of encoding
  112. output = output.Replace('_', '/'); // 63rd char of encoding
  113. switch (output.Length % 4) // Pad with trailing '='s
  114. {
  115. case 0: break; // No pad chars in this case
  116. case 2: output += "=="; break; // Two pad chars
  117. case 3: output += "="; break; // One pad char
  118. default: throw new System.Exception("Illegal base64url string!");
  119. }
  120. var converted = Convert.FromBase64String(output); // Standard base64 decoder
  121. return converted;
  122. }
  123. }
  124.  
  125. public class GoogleJsonWebToken
  126. {
  127. public static string Encode(string email, string certificateFilePath)
  128. {
  129. var utc0 = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);
  130. var issueTime = DateTime.Now;
  131.  
  132. var iat = (int)issueTime.Subtract(utc0).TotalSeconds;
  133. var exp = (int)issueTime.AddMinutes(55).Subtract(utc0).TotalSeconds; // Expiration time is up to 1 hour, but lets play on safe side
  134.  
  135. var payload = new
  136. {
  137. iss = email,
  138. scope = "https://www.googleapis.com/auth/gan.readonly",
  139. aud = "https://accounts.google.com/o/oauth2/token",
  140. exp = exp,
  141. iat = iat
  142. };
  143.  
  144. var certificate = new X509Certificate2(certificateFilePath, "notasecret");
  145.  
  146. var privateKey = certificate.Export(X509ContentType.Cert);
  147.  
  148. return JsonWebToken.Encode(payload, privateKey, JwtHashAlgorithm.RS256);
  149. }
  150. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement