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);
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);
}
}