Algs can get added to the cryptoconfig, but is there any way to get rid of them? or perhaps only have them work conditionally?
The problem is that the System.IdentityModel.Tokens.JwtSecurityTokenHandler.WriteToken(SecurityToken token) can no longer sign tokens if the global enable sha256 xml sigs is enabled.
Also, the hash algorithm on my cert is System.Security.Cryptography.SHA256Managed, but it changes to System.Security.Cryptography.SHA256Cng after RSAPKCS1SHA256SignatureDescription is added but either way the formatter is still System.Security.Cryptography.RSAPKCS1SignatureFormatter
static internal readonly string RsaSha256Namespace = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
/// Make Sha256 signature algorithm available in this process (not just Kentor.AuthServices)
[System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sha" )]
public static void GlobalEnableSha256XmlSignatures()
In IdSvr3, https://github.com/IdentityServer/IdentityServer3/blob/master/source/Core/Services/Default/DefaultTokenSigningService.cs#L90
This line in particular will blow up when
var handler = new JwtSecurityTokenHandler();
As you can see from this stack trace, something screwy happens when somewhere around CreateSignature()
2015-09-15 15:08:57,789  DEBUG IdentityServer3.Core.Services.Default.DefaultTokenService [(null)] - Creating JWT identity token
2015-09-15 15:08:57,867  DEBUG WebApi Diagnostics [(null)] - 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)
This ticket on the IdSvr3 side has more details on how I came to this conclusion: IdentityServer/IdentityServer3#1903
Okay, I feel like an idiot now.. but in case anyone else runs into this problem...
I had added the GlobalEnableSha256XmlSignatures because my app would blow up every time i connected to the dev IdP, and it turns out I needed to enable the option. HOWEVER. the production server has no such issues, so enabling it only caused me two days of grief.
If you're getting this error and you have GlobalEnableSha256XmlSignatures turned on, just rip that line of code out and everything will be hunky dory.
okay, so never mind.. i was able to get it to work because the signon cookie was still there. A new session blew up in my face when trying to verify the xml sig. I think I found a work around while troubleshooting this that can go on the kentor side.
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.
Microsoft Enhanced RSA and AES Cryptographic Provider
Tony, What work around did you use when verifying the XML signature to allow the Create JWT to work in tandem? Cheers.
@peterswallow See this comment on #337.
Is it possible to use the System.IdentityModel.Tokens.Jwt.CreateToken overload which accepts a SignatureProvider to workaround this? Or this is different to the CryptographyProvider?
@peterswallow AuthServices never calls Jwt.CreateToken, that's part of IdSrv3.
Our problem is that the signature algorithm is not part of a per-call or per-instance config. It's read from a process-global registry in http://referencesource.microsoft.com/#System.Security/system/security/cryptography/xml/signedxml.cs,796.
Unfortunately I don't see a way working around this in AuthServices, I see it as a bug in IdSrv3 or System.IdentityModel.
Add own SignatureDescriptor for SHA256
- Magically change CryptoServiceProvider to one that supports SHA256.
- Fixes #303
Been working on this today and found out that this can actually be fixed in AuthServices. X509AsymmetricSecurityKey contains some black magic to ensure that a crypto service provider supporting SHA256 is used. That magic is bypassed if a SHA256 algorithm is registered on an application level.