I've been signing JWT tokens for a couple of years with no problems. I recently upgraded to Windows 10 and when I try to sign a JWT token I get a CryptographicException of "Invalid algorithm specified".
I'm passing an X509Certificate2 into this method and I'm not doing anything else really.
System.IdentityModel.Tokens.JwtSecurityTokenHandler.CreateToken()
The signing certificate was previously created using SHA-1, so I even created a new signing certificate using SHA-256 RSA, but still no joy.
I read several SO questions that suggested I needed to enable the "Microsoft Enhanced RSA and AES Cryptographic Provider" or at least create my signing certificate using it. Many SO Qu's suggested adding this line, but still no luck.
CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
I also checked that this algorithm is in registry and found it in the Provider list and Provider type list. Unfortunately I don't have control of what algorithm the Jwt signing code uses as its all hidden within the System.Identity libraries.
Strangely, when I stepped into the code and looked at the Signature it mentioned it had an RSA Provider of "Microsoft Strong Cryptographic Provider", rather than the "Enhanced" one mentioned earlier, although from the MSDN documentation they appear to be pretty much the same.
I presume its complaining it can't find the Algorithm used to sign the actual token, rather than the algorithm to read or intepret the signing certificate?
What other checks can I do with the limited flexibility of the JwtSecurityTokenHandler code?
The full stack trace is:
at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash, Int32 cbHash, ObjectHandleOnStack retSignature)
at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash)
at System.Security.Cryptography.RSACryptoServiceProvider.SignHash(Byte[] rgbHash, Int32 calgHash)
at System.IdentityModel.Tokens.AsymmetricSignatureProvider.Sign(Byte[] input)
at System.IdentityModel.Tokens.JwtSecurityTokenHandler.CreateSignature(String inputString, SecurityKey key, String algorithm, SignatureProvider signatureProvider)
at System.IdentityModel.Tokens.JwtSecurityTokenHandler.CreateToken(String issuer, String audience, ClaimsIdentity subject, Lifetime lifetime, SigningCredentials signingCredentials, SignatureProvider signatureProvider)
at System.IdentityModel.Tokens.JwtSecurityTokenHandler.CreateToken(SecurityTokenDescriptor tokenDescriptor)