Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to encode JWT for APN tokenization (.NET, C#)

I'm trying to send Push Notifications to APN with tokenization. I tried to use a few libraries like jose-jwt and Microsot Jwt class for creating JWT token, but I can't wrap my head around it.

I get stuck on creating JWT and signing it with private key.

For communicating with certificates, I used PushSharp and it worked just fine. Can anyone help me with a working similar example but with tokens?

edit: following Apple's documentation here: https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html#//apple_ref/doc/uid/TP40008194-CH11-SW1

Sample code: the closest I came to something would look like this, but I don't know how to create CngKey properly

var payload = new Dictionary<string, object>()
            {
                { "iss", issuer },
                { "iat", DateTime.UtcNow }
            };

var headers = new Dictionary<string, object>()
            {
                 { "kid", keyIdentifier}
            };

CngKey key = CngKey.Create(CngAlgorithm.ECDsaP256); //how to create this CngKey

string token = Jose.JWT.Encode(payload, key, JwsAlgorithm.ES256, headers);
like image 454
user3790083 Avatar asked Jan 18 '17 15:01

user3790083


People also ask

What is JWT token C#?

JWT (JSON web token) Bearer Authentication and Authorization for APIs has become more and more popular in the realm of web development. It is an open standard that allows developers to transmit data between parties as a JSON object in a secure way.

How can I get HttpContext token?

You obtain a bearer (access) token from the HttpContext with the GetTokenAsync method by passing the access_token argument. This is how you add the access token to the request header: Copy request. Headers.


1 Answers

Thanks for your answers, had to contact many supports to get this done. Here is what the final result looked like.

/// <summary>
    /// Method returns ECDSA signed JWT token format, from json header, json payload and privateKey (pure string extracted from *.p8 file - PKCS#8 format)
    /// </summary>
    /// <param name="privateKey">ECDSA256 key</param>
    /// <param name="header">JSON header, i.e. "{\"alg\":\"ES256\" ,\"kid\":\"1234567899"\"}"</param>
    /// <param name="payload">JSON payload, i.e.  {\"iss\":\"MMMMMMMMMM"\",\"iat\":"122222222229"}"</param>
    /// <returns>base64url encoded JWT token</returns>
    public static string SignES256(string privateKey, string header, string payload)
    {
        CngKey key = CngKey.Import(
            Convert.FromBase64String(privateKey), 
            CngKeyBlobFormat.Pkcs8PrivateBlob);

        using (ECDsaCng dsa = new ECDsaCng(key))
        {
            dsa.HashAlgorithm = CngAlgorithm.Sha256;
            var unsignedJwtData = 
                Url.Base64urlEncode(Encoding.UTF8.GetBytes(header)) + "." + Url.Base64urlEncode(Encoding.UTF8.GetBytes(payload));
            var signature = 
                dsa.SignData(Encoding.UTF8.GetBytes(unsignedJwtData));
            return unsignedJwtData + "." + Url.Base64urlEncode(signature);
        }
    }
like image 119
user3790083 Avatar answered Sep 17 '22 07:09

user3790083