Hi security experts,
I am trying to validate the JWT token returned from ADAL (Experimental version) .acquireToken() after a successful login against a B2C tenant. I have obtained the runtime JWK token from ../discovery/v2.0/keys?p={myloginpolicy}. I
am then trying to extract the public key and validate the signature of the JWT token received earlier via:
WebClientwc =newWebClient();
varsigningTokenJwt = wc.DownloadString("https://login.microsoftonline.com/{myrealm}.onmicrosoft.com/discovery/v2.0/keys?p={myloginpolicy}");
dynamicdynObj =JsonConvert.DeserializeObject(signingTokenJwt);
n = dynObj.keys[0].n;
exp = dynObj.keys[0].e;
RSAParametersRSAKeyInfo =newRSAParameters();
RSAKeyInfo.Modulus =Encoding.UTF8.GetBytes(n);
RSAKeyInfo.Exponent =Encoding.UTF8.GetBytes(exp);
RSACryptoServiceProvidercsp
= newRSACryptoServiceProvider();
csp.ImportParameters(RSAKeyInfo);
RSAPKCS1SignatureDeformatterRSADeformatter
= newRSAPKCS1SignatureDeformatter(csp);
RSADeformatter.SetHashAlgorithm("SHA256");
// Bit hacky this bit for the time being to get the parts of the jwt token received that would have been signed.
byte[] data =Encoding.UTF8.GetBytes(jwtToken.Split('.')[0]+"."+
jwtToken.Split('.')[1]);
byte[]
signature = Encoding.UTF8.GetBytes(jwtToken.Split('.')[2]);
byte[]
hash = sha1.ComputeHash(data);
System.Diagnostics.Trace.WriteLine(csp.VerifyHash(hash,CryptoConfig.MapNameToOID("SHA256"),
signature));
However, this is currently throwing an exception when I try to import the parameters into the CyptoProviderService.
You may ask why I am doing this. I have a set of SOAP web services that will be validating the bearer tokens (so cant use OWIN :-( but still have the need to confirm the token has come from a valid source and has not been tampered with).
Two question then:
1. Am I on the right track in terms of validating the signature?
2. If the above strategy is correct, what am I missing in terms of being able to successfully execute the validation?
Thanks in advance
edit: Fixed the exception, e needed to base64 decoded doh!