How to create a signing certificate for a JWT token

Hackered
Sunday, October 26, 2014
by Sean McAlinden

As JWT tokens are becoming an increasingly prominent format for OAuth 2 tokens, it is really important to know how to make them and how to create a self signed certificate for use in development and test. The main purpose of this post is actually the following make cert statement as it will create a fully functioning self signed certificate for JWT token signing.

Creating a signing certificate

makecert -r -pe -n "CN=My JWT Signing Cert" -eku 1.3.6.1.5.5.7.3.3 -ss my -sr localMachine -len 2048 -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 "MyJWTSigningCert.cer"

NOTE: You may also need to copy the certificate into the Trusted People store.

Creating a token

The following is an example of a bare minimum OAuth 2 token controller. It does not validate the user at all so just treat it as an example of how to generate a JWT token (this is not production code). Download the Microsoft JWT handler from nuget. The CertificateHelper code is just some simple code for getting a certificate from the certificate store, I'll put an example at the end of the post for completeness.

[RoutePrefix("auth/token")]
public class TokenController : ApiController
{
    [Route("")]
    public IHttpActionResult Post([FromBody]OAuthPasswordGrantRequestModel oAuthPasswordGrantRequestModel)
    {
        var cert = CertificateHelper.FindByThumbprint(""Ž"Ž"Ž"Žb29fde59011709518392183bc643431262a9dd5e", StoreName.My, StoreLocation.LocalMachine);

        var claims = new List<Claim>
            {
                new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", oAuthPasswordGrantRequestModel.Username)
            };

        var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();

        var x509SigningCredentials = new X509SigningCredentials(cert);
        SecurityToken securityToken = new JwtSecurityToken(
            "MyIssuer",
            audience: "MyAudience",
            claims: claims,
            lifetime: new Lifetime(DateTime.UtcNow, DateTime.UtcNow.AddMinutes(60)),
            signingCredentials: x509SigningCredentials);

        var jwtToken = jwtSecurityTokenHandler.WriteToken(securityToken);

        return Ok(new TokenResult() { access_token = jwtToken });
    }
}

And there it is, give the endpoint a call and you will get a valid signed JWT token

Certificate Helper

public static class CertificateHelper
{
    public static X509Certificate2 FindByThumbprint(
        string thumbprint,
        StoreName storeName,
        StoreLocation storeLocation)
    {
        var certificateStore = new X509Store(storeName, storeLocation);
        certificateStore.Open(OpenFlags.ReadOnly);

        foreach (var certificate in certificateStore.Certificates)
        {
            if (certificate == null || certificate.Thumbprint == null)
            {
                continue;
            }

            if (String.Equals(certificate.Thumbprint, thumbprint, StringComparison.CurrentCultureIgnoreCase))
            {
                certificateStore.Close();
                return certificate;
            }
        }

        throw new ArgumentException(
            string.Format("Cannot find certificate with thumbprint {0} in certificate store ", thumbprint));
    }
}