jwt-dotnet/jwt

RSA256 does not work Says Invalid Algorithm name

mdhruv1 opened this issue · 19 comments

These are the steps I am following. I am trying to make a jwt token using RS256 having a public and private key
Generate a pem file using openssl on mac then copy it

The code below I was able to get to work on hmac but not for RSA256. I get an error not a valid algotrithm for RS256.

If you can take a look at this code below and guide to do RS256 that will be awesome.
The exact steps u used for generating a certificate.

   public Boolean createJWT_old(string model, string serial, string assetid, out string encodedJWT)
        {
            const string cIssuer = "Online JWT Builder";
            const int cTokenExpiryHrs = 1;
            const string cAudience = "www.bbbb.com"; // app://passlink
            const string cSubject = "injector@bbbb.com";



            var payload = new Dictionary<string, object>
            {
                { "iss"  , cIssuer},
                { "iat"  ,(long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds},
                { "exp"  ,(long)((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds+ cTokenExpiryHrs * 3600)},
               // { "exp"  ,(DateTimeOffset.UtcNow.AddHours(cTokenExpiryHrs)).ToUnixTimeSeconds()},
               // { "exp"  ,(long)(DateTimeOffset.UtcNow.AddHours(cTokenExpiryHrs) -  new DateTime(1970, 1, 1)).TotalSeconds},
                { "aud" , cAudience},
                { "sub" , cSubject},
                { "model" , model},
                { "serial" , serial},
                { "asset" , assetid}
            };
            try
            {
                IJwtAlgorithm algorithm =
                    new HMACSHA256Algorithm();
                    //new RS256Algorithm()

                IJsonSerializer serializer = new JsonNetSerializer();
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);

                encodedJWT = encoder.Encode(payload, this.encodeSecret);
                return true;
            }
            catch (Exception e)
            {
                encodedJWT = Constants.cErrCreateFailed;
                Console.Error.WriteLine(e.Message);
                return false;
            }
        }

Hi, happy to help. Can you please update your code with the exact way you construct the algorithm object and the cert you pass to its constructor.

To create the certs I used mac with the following commands:

openssl req -new -newkey rsa:512 -nodes -keyout CA_PrivateKey.key -out CA_SigningRequest.csr
choose country US
common name = passconnect
challenge pwd = password

openssl x509 -req -days 2000 -in CA_SigningRequest.csr -signkey CA_PrivateKey.key -out CA_Certificate.crt

openssl pkcs12 -export -out CA_Certificate.pfx -inkey CA_PrivateKey.key -in CA_Certificate.crt
password=password

This works in core net 3.0 . When I try to use this code in dot net framework 4.0
say invalid algorithm name,

   private static void testCertificates()
    {
        const string cIssuer = "Passlink";
        const int cTokenExpiryHrs = 1;
        const string cAudience = "www.bbbb.com"; // app://passlink
        const string cSubject = "info@bbbb.com";

        X509Certificate2 certificate = new X509Certificate2("CA_Certificate.pfx", "password");

        IJwtAlgorithm algorithm = new RS256Algorithm(certificate);

        IJsonSerializer serializer = new JsonNetSerializer();

        IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();

        IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);

        var payload = new Dictionary<string, object>

{

{ "iss" , cIssuer},

{ "iat" ,(long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds},

{ "exp" ,(long)((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds+ cTokenExpiryHrs * 3600)},

{ "aud" , cAudience},

{ "sub" , cSubject},

};
        var encodedJWT = encoder.Encode(payload, "");
        Console.WriteLine(encodedJWT);
    }

Perhaps you didn't mean to close it. Did you?

Make sure this code works with our error:

var certificate = ...
Debug.Assert(certificate.PublicKey is not null);
Debug.Assert(certificate.HasPrivateKey);

Also post full exception message and stack trace.

I wonder what algorithm should I use if I repeat the steps and I get "sha512RSA" when I look at the certificate.m_signature.Algorithm.Friendlyname= "sha512RSA"

I am getting invalid algorithm when I use RS512:

 IJwtAlgorithm algorithm = new RS512Algorithm(certificate);

These are the steps I used to create the certificate

openssl req -x509 -nodes -sha512 -newkey rsa:2048 -keyout 512key.pem -out 512cert.pem -days 3650

openssl pkcs12 –export –in 512cert.pem –inkey 512key.pem –CSP “Microsoft Enhanced RSA and AES Cryptographic Provider” –out 512pfx.pfx

to do a p12 conversion

openssl pkcs12 -export -out 512Cert.p12 -in 512cert.pem -inkey 512key.pem

Hi! Sorry, still can't find the full exception stack trace. Please post it here so I could assist you better.

This is the stack trace:

   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 JWT.Algorithms.RSAlgorithm.Sign(Byte[] bytesToSign)
   at JWT.JwtEncoder.Encode(IDictionary`2 extraHeaders, Object payload, Byte[] key)
   at RSA.Program.testCertificates() in c:\users\test\documents\visual studio 2015\Projects\RSA\RSA\Program.cs:line 108

Attached is the pfx I have used for the certificate

This is certificate file I am using attached . I had emailed you the file

All I am trying to do is to use a RS256 certificate to encode and decode a JWT token. I am using .net 4.0 if you can help me with a work example that will be awesome.

I see, so the exception isn't from the library but from the PKI API of .NET. I think it's a mismatch between RSxyz and the certificate you've created and pass.

Please list the exceptions you're getting when using other algorithms.

getting when using other algorithms.

This code works when I use HMAC.

How can I specify for RS256 to use "sha1RSA" as the algorithm. That i not clear to me. That should solve the issue I think

HMAC is a symmetric (hashing) algorithm and doesn't use a certificate, hence works.

I meant try RS work a different number, which represents the length of the key. It should match the parameters you pass when create the underlying certificate.

Namely RS512.

So how does that work . Zipped the PFX file . The algortitm in certificate says SHA1RSA so what should i be using

CA.zip

I used the 512 instead of 256 still says invalid algorithm.

I'm not familiar with openssl.exe but I see you pass 512 so you should use RS512, I guess. Try to run on .NET 6 and .NET 4.6.2 to make sure it's not a lower framework version issue.

I have opened another issue . The example for RSA256 the
var token = encoder.Encode(payload);
It is missing parameters . If we can edit it and see that will be awesome

Thanks! I'll fix the documentation.

For the issue itself, I'd suggest to ask on Stack Overflow, there will be more experts in the area with experiencing for .NET 4.0, I don't have it, sorry.