Skip to content
This repository has been archived by the owner on Sep 18, 2021. It is now read-only.

Invalid algorithm specified #1903

Closed
tonyeung opened this issue Sep 14, 2015 · 26 comments
Closed

Invalid algorithm specified #1903

tonyeung opened this issue Sep 14, 2015 · 26 comments
Labels

Comments

@tonyeung
Copy link

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
Copy link
Author

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
Copy link
Author

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
Copy link
Author

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
Copy link
Author

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
Copy link
Member

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

@tonyeung
Copy link
Author

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
Copy link
Author

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
Copy link
Author

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
Copy link
Author

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
Copy link
Author

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

@tonyeung
Copy link
Author

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

@tonyeung
Copy link
Author

    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
Copy link
Author

opened a ticket with kentor: Sustainsys/Saml2#303

@tonyeung
Copy link
Author

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
Copy link
Author

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
Copy link
Author

@tonyeung
Copy link
Author

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.

@ianhorton
Copy link

@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
Copy link

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.

@keithpecka3
Copy link

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

@AndersAbel
Copy link

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

@muizsyed
Copy link

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

@AndersAbel
Copy link

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

@AndersAbel
Copy link

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/

@danielmeza
Copy link

I´m getting this error when I move the IS to another IIS server, different from dev; I'm stuck with this issue.

@AndersAbel
Copy link

@danielmeza Please open a new issue as this one is closed since mid last year.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

8 participants