1

I am attempting to generate a JWT using a ES256 algorithm to be validated by talk desk (documentation: https://docs.talkdesk.com/docs/using-a-signed-jwt).

BUT I have an ADO.net project so I can't use any of the frameworks they sugested, so I thought the right path would be to use the https://github.com/dvsekhvalnov/jose-jwt library.

The jose-jwt documentation state:

ES256, ES384, ES256 ECDSA signatures requires CngKey (usually private) elliptic curve key of corresponding length. Normally existing CngKey loaded via CngKey.Open(..) method from Key Storage Provider. But if you want to use raw key material (x,y) and d, jose-jwt provides convenient helper EccKey.New(x,y,d).

I'm having trouble understanding how does my private key that I receive from talkdesk will fit in all this.

Bellow is my code:

public static string Encode(TenantModel tenant)
        {

            byte [] keyBytes= Encoding.UTF8.GetBytes(tenant.private_key); 
            var header = new Dictionary<string, object>()
            {
                { "header", new { kid = tenant.key_id} }
                //{ "algorithm", tenant.key_algorithm }
            };

            var payload = new Dictionary<string, object>()
            {
                { "iss", tenant.client_id },
                { "sub", tenant.client_id },
                { "aud", "https://" + tenant.account_name + ".talkdeskid.com/oauth/token" },
                { "jti", Guid.NewGuid().ToString() },
                { "exp", DateTime.Now.AddSeconds(300) },
                { "iat", DateTime.Now }
            };

            var privatekey = new ECDsaCng(CngKey.Create(CngAlgorithm.ECDsaP256));
            privatekey.SignData(keyBytes, 0, keyBytes.Length, HashAlgorithmName.SHA256);        

            return Jose.JWT.Encode(payload, privatekey, JwsAlgorithm.ES256,header);
        }

I've also seen that using the CngKey.Open(..) method implies the creation of a certificate and I would like to stay away from that If possible.

André Moura
  • 53
  • 1
  • 11

1 Answers1

2

I encountered the same issue connecting to Apple's app store connect API. They hand you a .p8 file with a private key and it is not clear how to integrate this with jose-jwt which assumes you have X, Y, and D or a CngKey which is a data object I'm not very familiar with. But in the end, it wasn't very hard at all.

Open up the .p8 file in a text editor and copy out the private key. It is the character data between the "---- BEGIN PRIVATE KEY ----" header and footer. Remove newlines. You have a single Base64 encoded blob of data.

var privateKey = "MAGTAguM[...]qaTKB2";

var key = CngKey.Import(Convert.FromBase64String(privateKey), 
                        CngKeyBlobFormat.Pkcs8PrivateBlob);

return Jose.JWT.Encode(payload, key, JwsAlgorithm.ES256, extraHeaders);
Matt
  • 436
  • 3
  • 6