1 module jwt.algorithms; 2 3 import std.digest.hmac; 4 import std.digest.sha; 5 import std.string : representation; 6 import std.base64; 7 import std.stdio; 8 9 import jwt.exceptions; 10 11 /** 12 * string literal used to represent signing algorithm type 13 */ 14 enum JWTAlgorithm : string { 15 NONE = "none", // string representation of the none algorithm 16 HS256 = "HS256", // string representation of hmac algorithm with sha256 17 HS384 = "HS384", // string representation of hmac algorithm with sha348 18 HS512 = "HS512" //string representation of hmac algorithm with sha512 19 } 20 21 /** 22 * an alias for base64 encoding that is url safe and removes the '=' padding character 23 */ 24 alias URLSafeBase64 = Base64Impl!('-', '_', Base64.NoPadding); 25 26 /** 27 * signs the given data with the secret using the given algorithm 28 * Params: 29 * secret = the secret used to sign the data 30 * data = the data that is to be signed 31 * alg = the algorithm to be used to sign the data 32 * Returns: signature of the data 33 */ 34 string sign(string secret, string data, JWTAlgorithm alg) { 35 36 switch(alg) { 37 38 case JWTAlgorithm.HS256: 39 auto signature = HMAC!SHA256(secret.representation); 40 signature.put(data.representation); 41 return URLSafeBase64.encode(signature.finish()); 42 43 case JWTAlgorithm.HS384: 44 auto signature = HMAC!SHA384(secret.representation); 45 signature.put(data.representation); 46 return URLSafeBase64.encode(signature.finish()); 47 48 case JWTAlgorithm.HS512: 49 auto signature = HMAC!SHA512(secret.representation); 50 signature.put(data.representation); 51 return URLSafeBase64.encode(signature.finish()); 52 53 case JWTAlgorithm.NONE: 54 return ""; 55 56 default: 57 throw new UnsupportedAlgorithmException(alg ~ " algorithm is not supported!"); 58 59 } 60 61 } 62 /// 63 unittest { 64 65 string secret = "supersecret"; 66 67 string data = "an unstoppable force crashes into an unmovable body"; 68 69 string signature = sign(secret, data, JWTAlgorithm.HS512); 70 71 assert(signature.length > 0); 72 73 signature = sign(secret, data, JWTAlgorithm.NONE); 74 75 assert(signature.length == 0); 76 77 }