"invalid algorithm specified" after adding RSAPKCS1SHA256SignatureDescription to cryptoconfig #246

Closed
tonyeung opened this Issue Sep 15, 2015 · 13 comments

Projects

None yet

6 participants

@tonyeung

Trying to write a token using JwtSecurityTokenHandler.WriteToken()
Get error: Invalid algorithm specified

Stack trace:

Operation=ReflectedHttpActionDescriptor.ExecuteAsync, Exception=System.Security.Cryptography.CryptographicException: Invalid algorithm specified.
   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.Security.Cryptography.RSAPKCS1SignatureFormatter.CreateSignature(Byte[] rgbHash)
   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.WriteToken(SecurityToken token)

Found out the problem is when I add this line to my project in order to verify some xml signatures.
CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");

So right now I can either validate xml or create tokens. Except I can't create the token until i've validated the xml...

@tonyeung

I don't know why the cert doesn't work, but after I created a new cert and specified Microsoft Enhanced RSA and AES Cryptographic Provider as the CSP, it worked. If anyone else has this problem, please note that on the cert request either from the MMC or IIS will not let you chose the CSP (the option should be there but it will be hidden AND disabled). You will need to generate the request via certreq.exe. Its a PITA but that's the only work around that I know of right now.

@brentschmaltz
Member

the reason is the default CSP doesn't support SHA2, when you created the cert with 'enhanced', you triggered a different CSP to be instantiated that supports SHA2. It is a bit quirky to be sure.

@tonyeung

@brentschmaltz Is there a way to specify which one I need to use? if I don't add RSAPKCS1SHA256SignatureDescription to the cryptoconfig, signing works fine. I looked for away to remove description but there wasn't anything public I could call.

@brentschmaltz
Member

Have you considered a custom AsymmetricSignatureProvider and pass that as a parameter to CreateToken?

@brentschmaltz brentschmaltz reopened this Sep 18, 2015
@brentschmaltz
Member

@tonyeung now I see why you are confused. Which version are you using?

@brentschmaltz brentschmaltz added this to the RC1 milestone Oct 5, 2015
@tonyeung
tonyeung commented Oct 5, 2015

do you mean nuget version?

@tushargupta51
Contributor

@tonyeung yes the nuget package version

@tushargupta51
Contributor

@tonyeung did you find the package version?

@tonyeung

sorry i got side tracked: 4.0.2.206221351, here's the package config. https://github.com/IdentityServer/IdentityServer3/blob/master/source/Core/packages.config

@brentschmaltz brentschmaltz modified the milestone: Next 4.x Release, RC1 Oct 19, 2015
@peterswallow

Any word with this one? I've got the same problem (validating XML and Creating JWT tokens in same application). I can't change the JwtSecurityTokenHandler code, so presume I need to change my XML validation code but not sure how). Please help!!! :)

@polita polita added the Investigate label May 19, 2016
@AndersAbel
AndersAbel commented Jun 15, 2016 edited

Finally have had some time to look into this from the Kentor.AuthServices end. It's a SAML2 OWIN middleware that's often used together with IdentityServer3, which relies on System.IdentityModel.Tokens.Jwt. So the combination of enabling SHA256 xml signatures for SAML2 in Kentor.AuthServices and using the JWT token handler should be fairly common.

The reason for all of this is actually in the .NET framework where X509AsymmetricSecurityKey.GetSignatureFormatter contains some black magic to copy the key to a new RsaCryptoServiceProvider with type = 24, instead of the default one with type=1 that doesn't support SHA256. This can be handled by having a certificate that specifies a CSP with type 24 (with 24 meaning Microsoft Enhanced RSA and AES Cryptographic Provider, so that's the solution that @tonyeung suggests above).

For now I've added the same black magic to the SignatureDesription being used by Kentor.AuthServices (see KentorIT/authservices#303) which should solve this particular conflict.

I'm not sure however if the SignatureDescription is the right place to replace to replicate the logic from X509AsymmetricSecurityKey.GetSignatureFormatter. I think it would be better if X509AsymmetricSecurityKey.GetSignatureFormatter did the magic both when the algorithm is registered and in the fallback.

I wrote a blog post with some in depth analysis: https://coding.abel.nu/2016/06/why-enabling-sha256-support-for-xml-signatures-breaks-jwt-signing/

@polita
Member
polita commented Jul 13, 2016

Fixed in 4.6.2.

@polita polita closed this Jul 13, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment