Invalid algorithm specified #1903

Closed
tonyeung opened this Issue Sep 14, 2015 · 24 comments

Projects

None yet

7 participants

@tonyeung

When trying to get my JWT token signed, I get this error:

2015-09-14 14:53:55,753 [5] DEBUG IdentityServer3.Core.Services.Default.DefaultTokenService [(null)] - Creating JWT identity token
2015-09-14 14:53:56,050 [5] DEBUG WebApi Diagnostics [(null)] - Operation=ReflectedHttpActionDescriptor.ExecuteAsync, Exception=System.Security.Cryptography.CryptographicException: Invalid algorithm specified.

I'm guessing it has something to do with the cert i'm using. This is a cert we got from a trusted CA and not self signed. The cert algorithm is sha256RSA according to the cert properties.
Am I doing something wrong?

When I tried researching this it sounds like it might be the Cryto Service Provider on the Win2012 server we're using. If that's the case, is there any way to make this work other than requesting (and paying for) a new cert?

My code when assigning the cert to SigningCertificate on the options:

        var store = new X509Store(StoreLocation.LocalMachine);
        store.Open(OpenFlags.ReadOnly);
        var certs = store.Certificates.Find(X509FindType.FindByThumbprint, "thumbprint", false);
        if (certs.Count > 0)
        {
            options.SigningCertificate = certs[0];
        }
        store.Close();
@tonyeung

okay, so this is strange.. when i created a console app, it works..

        var store = new X509Store(StoreLocation.LocalMachine);
        store.Open(OpenFlags.ReadOnly);
        var certs = store.Certificates.Find(X509FindType.FindByThumbprint, "thumb", false);
        if (certs.Count > 0)
        {
            Console.WriteLine("signing token");
            var jwt = new JwtSecurityToken(
                "issuer",
                "audience",
                null,
                DateTime.UtcNow,
                DateTime.UtcNow.AddSeconds(10000),
                new X509SigningCredentials(certs[0]));

            Console.WriteLine(jwt.ToString());
        }
        store.Close();

        Console.ReadLine();
@tonyeung

So I was barking up the wrong tree, with the logging, i know that the problem is when the JwtSecurityTokenHandler.WriteToken(jwt) is when the problem starts

@tonyeung

more logging indicates that it is at the JwtSecurityTokenHandler.WriteToken. However, when I compare the jwt being passed in, the only difference between the two output is the nonce and the iat. IdSvr is running on the same server as my test console application, and they're referencing the same cert. I don't really understand how it can work in one and not the other. Perhaps the token.jwt package is different.

@tonyeung

the only difference was the json.net version, made them the same version and console still gets me a result and idsvr still bombs out

@leastprivilege
Member

Sorry - no idea what's going on. Keep us posted.

@tonyeung

The only difference I can tell between the owin self hosted identity server and the console app is that one uses System.Security.Cryptography.SHA256Cng and the other uses System.Security.Cryptography.SHA256Managed by default

Unfortunately, that's not what's causing an issue. I forced each of the apps to use one and then the other, and the same results happen. IdentityServer crashes, and console app keeps chugging along

@tonyeung

looking at the stacktrace for anyone interested:

   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 IdentityServer3.Core.Services.Default.DefaultTokenSigningService.CreateJsonWebToken(Token token, SigningCredentials credentials1)

I was able to get the source for everything up to RSACryptoServiceProvider.SignHash but I wasn't able to debug into it.

@tonyeung

A bit more debugging shows that the problem is only happening in idsvr. I created a new self hosted owin project,stuck the same code as the console app, and it also completes without a hitch.

@tonyeung

I stuck the same piece of code before idsvr gets started and it still works, going to to start moving it around to see if i can find when it starts breaking

@tonyeung

okay, so if i stick my test code before app.UseIdentityServer(options); then it works, right after it, then it stops working

@tonyeung

soooooooooo..
Kentor.AuthServices.Configuration.Options.GlobalEnableSha256XmlSignatures();

@tonyeung
    static internal readonly string RsaSha256Namespace = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";

    /// <summary>
    /// Make Sha256 signature algorithm available in this process (not just Kentor.AuthServices)
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sha" )]
    public static void GlobalEnableSha256XmlSignatures()
    {
        CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), RsaSha256Namespace);
    }
@tonyeung

opened a ticket with kentor: KentorIT/authservices#303

@tonyeung

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.

@tonyeung tonyeung closed this Sep 15, 2015
@tonyeung

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.

@tonyeung tonyeung reopened this Sep 15, 2015
@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.

@tonyeung tonyeung closed this Sep 17, 2015
@ianhorton

@tonyeung - I had a similar issue, I am working with Okta and I changed the Signature Algorithm on my app to use RSA_SHA1, I could then remove the call to Options.GlobalEnableSha256XmlSignatures(); from my Startup class.

@Bidou44
Bidou44 commented Jan 6, 2016

I tried the solution proposed by @tonyeung, but I then have the following exception:
CryptographicException: The data to be decrypted exceeds the maximum for this modulus of 128 bytes.

What I didn't do is to "generate a request with the certreq.exe". To be honest, I do not understand what I have to do here since I'm trying to make the whole thing work on my localhost with a self-signed certificate.

Any help would be greatly appreciated.

@keithpeckagent3

Any update on this? I'm using the ComponentSpace SAML library. It's also adding signatures via CryptoConfig.AddAlgorithm and breaking IdentityServer.

@AndersAbel

I've now applied a workaround in Kentor.AuthServices to this (see KentorIT/authservices#303). It's basically the same black magic as the .NET Framework does when no SHA256 xml signature algorithm is registered.

@muizsyed

@AndersAbel Any idea when the workaround will get pushed to Nuget?

@AndersAbel

Within a week. I'm working on some more stuff that I want to have included in a release.

@AndersAbel

Kentor.AuthServices 0.19.0 is now released and contains this fix. For an explanation of the issue, please see https://coding.abel.nu/2016/06/why-enabling-sha256-support-for-xml-signatures-breaks-jwt-signing/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment