I have used JSONWebToken
npm module to generate a jot:
var jwt = require('jsonwebtoken');
var payload = {
"iss": "https://secure.example.com/",
"exp": 1410819380,
"http://example.com/orgnum": "987987987",
"http://example.com/user": "me@example.com"
};
var token = jwt.sign(payload, 'secret');
console.log(token);
This gives me the following output:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3NlY3VyZS5leGFtcGxlLmNvbS8iLCJleHAiOjE0MTA4MTkzODAsImh0dHA6Ly9leGFtcGxlLmNvbS9vcmdudW0iOiI5ODc5ODc5ODciLCJodHRwOi8vZXhhbXBsZS5jb20vdXNlciI6Im1lQGV4YW1wbGUuY29tIiwiaWF0IjoxNDA4Mzk0Mjk2fQ.5X5LTg4wxDF2p49xtsRcG4S9Yk4qSfW1tMEU0AquBhc
Since I'm not specifying what algorithm I want, it uses SHA256.
Now, I try to verify this in c#. That didn't turn out easy...
I get an exception about the key size:
IDX10603: The 'System.IdentityModel.Tokens.InMemorySymmetricSecurityKey' cannot have less than: '128' bits. Parameternavn: key.KeySize The actual size was 48.
I I try to extend the key, I get a new error when creating the symmetric key:
Invalid length for a Base-64 char array or string
I recon this has something to do with the way I'm telling the .net code about my key. Since the SymmetricKeyIssuerSecurityTokenProvider
constructor parameter is named base64Key
, I have tryed to Base64Url-encode my key:
var secret = Base64UrlEncoder.Encode("secret");
TokenValidationParameters validationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
IssuerSigningTokens = new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret).SecurityTokens
};
So, what are I missing here?
Why can jsonwebtoken
generate and validate jots with short keys while .net can not?
And why can't .net accept the keys I give it?
Here's the complete .net code with a jot signed with a long key:
var jwtToken =
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3NlY3VyZS5leGFtcGxlLmNvbS8iLCJleHAiOjE0MTA4MTkzODAsImh0dHA6Ly9leGFtcGxlLmNvbS9vcmdudW0iOiI5ODc5ODc5ODciLCJodHRwOi8vZXhhbXBsZS5jb20vdXNlciI6Im1lQGV4YW1wbGUuY29tIiwiaWF0IjoxNDA4Mzk1NjY4fQ.ZceiiEO_Mn5_GZp5D_r68VTT33fbocn1BTTznD6u3cs";
var secret = Base64UrlEncoder.Encode("super duper secret with some more on top");
TokenValidationParameters validationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
IssuerSigningTokens = new SymmetricKeyIssuerSecurityTokenProvider("issuer", secret).SecurityTokens
};
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler()
{
Configuration = new SecurityTokenHandlerConfiguration()
{
CertificateValidationMode = X509CertificateValidationMode.None
}
};
SecurityToken validatedToken;
var claimsPrincipal = tokenHandler.ValidateToken(jwtToken, validationParameters, out validatedToken);
return claimsPrincipal.Claims;
Updated:
I'm only using Microsoft-stuff in this code. I'm using the Owin
packages Microsoft.Owin.Security.Jwt
version 2.1.0
with System.IdentityModel.Tokens.Jwt
version 4.0.0-RC2
.
There are multiple blog posts out there stating that you'll need to manually update the System.IdentityModel.Tokens.Jwt
package.
Try to use
TextEncodings.Base64Url.Decode
api fromMicrosoft.Owin.Security.Jwt
package to decode the signing keyThen I do following to validate token:
Correct about the key not being less that 128 bits, since support is only for AES that is the minimum.
You can use your own SignatureProvider.
I also think you are using older bits. Have a look at the latest. http://www.nuget.org/packages/System.IdentityModel.Tokens.Jwt/
If you have any issues, let me know.
I'm not sure what API you are using, since the official Microsoft one does not contain the properties that you are using. My guess would be, you are using an outdated version.
I took the API from this Nuget package. And this is the code, that worked for me:
Note, that I had to resize the array containing the key so that key length passes the validation. It appears that they key length for HMAC is always equal to the block size, and for SHA256 it's 512 bits. There is MinimumSymmetricKeySizeInBits static property that defines the minimum length of a SimmetricKey, but it appears it can't be set to be less than 128.