Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JWT.Encode - ECDH_ES - A256GCM - Not supported in Linux #176

Closed
daniel-botero-cko opened this issue Mar 21, 2022 · 3 comments
Closed

JWT.Encode - ECDH_ES - A256GCM - Not supported in Linux #176

daniel-botero-cko opened this issue Mar 21, 2022 · 3 comments

Comments

@daniel-botero-cko
Copy link

daniel-botero-cko commented Mar 21, 2022

Hello,

I have tried to make JWT.Encode() work with .net5 and in Linux without success.
It seems that CngKey is only supported in the Windows platform.

Is there a workaround to Encrypt a payload using Alg: ECDH_ES Enc: A256GCM using jose-jwt library?

Below is the code that works in Windows:

[Fact]
        public void Tests2()
        {
            var privCngKey = GetCngKeyPrivateKey();
            var pubCngKey = GetCngKeyPublicKey();
            //given
            string json = "{\"num\":\"1234567891234567\",\"ram\":\"1223\"}";
            //when
            string token = Jose.JWT.Encode(json, pubCngKey, JweAlgorithm.ECDH_ES, JweEncryption.A256GCM);
            //then
            Console.Out.WriteLine("ECDH-ES A256GCM = {0}", token);
            Assert.Equal(Jose.JWT.Decode(token, privCngKey), json);
        }


        private static CngKey GetCngKeyPrivateKey()
        {
            var certificate = @"-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIAitDbKBDiQpQ3Q64tAq5UFge4MyppCbxBk5OgHkt+UMoAoGCCqGSM49
AwEHoUQDQgAE6z98vdUZNeuaEXcoxLY9dSylEI7HNr+Uj/CYwlbE97l4PB5pZw0R
3fKshknUKb2t5I+2v+XD4P9fsqJqBJZhkQ==
-----END EC PRIVATE KEY-----";
            var ecdSa = ECDsa.Create("ecdSa");
            ecdSa.ImportFromPem(certificate);
            var ecParameters = ecdSa.ExportParameters(true);
            return EccKey.New(ecParameters.Q.X, ecParameters.Q.Y, ecParameters.D, CngKeyUsages.KeyAgreement);
        }

        private static CngKey GetCngKeyPublicKey()
        {
            var certificate = @"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6z98vdUZNeuaEXcoxLY9dSylEI7H
Nr+Uj/CYwlbE97l4PB5pZw0R3fKshknUKb2t5I+2v+XD4P9fsqJqBJZhkQ==";
            var ecdSa = ECDsa.Create();
            ecdSa.ImportSubjectPublicKeyInfo(Convert.FromBase64String(certificate),out var _);
            var ecParameters = ecdSa.ExportParameters(false);
            var cngKey = EccKey.New(ecParameters.Q.X, ecParameters.Q.Y, usage:CngKeyUsages.KeyAgreement);
            return cngKey;
        }
@dvsekhvalnov
Copy link
Owner

Hi @daniel-botero-cko ,

yeah, you right CngKey is Windows only.

You can do AES-GCM on Linux - there is managed implementation in .net core, fully supported by library.

But there are no EC Diffie-Hellman managed implementation, so no luck at the moment.

@daniel-botero-cko
Copy link
Author

daniel-botero-cko commented Mar 21, 2022

@dvsekhvalnov Thanks for your message.

Sorry for this question (I am not very good at cryptography); what is the difference between AES-GCM and ECDH_ES-A256GCM?

If I encrypt the JSON below with AES-GSM it will produce a completely different JWE than if I have done it with ECDH_ES-A256GCM?

"{\"num\":\"1234567891234567\",\"ram\":\"1223\"}";

@dvsekhvalnov
Copy link
Owner

@daniel-botero-cko sure thing:

So, encrypted JWTs are actually 2 step process:

  1. Content of token encrypted using symmetric key, this is what AES-GCM or AES-CBC-HMAC algorithms are used for
  2. The encryption key itself is "wrapped" (protected) with another asymmetric/symmetric encryption algorithm to ensure nobody except recipient can figure it out while in-transit, this is where algorithms like ECDH_ES or RSA_OAEP are used.

Given that: ECDH_ES-A256GCM - is ECHS_ES to protect key and AES-GCM-256 to encrypt token content.
While A256GCMKW - is AES-GCM-256 to protect key and again AES-GCM-256 to encrypt content with different symmetric key (shared key)

Hope it makes it little bit more clear :)

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

No branches or pull requests

2 participants