如何为 APN 标记化(.NET、C#)编码 JWT
Posted
技术标签:
【中文标题】如何为 APN 标记化(.NET、C#)编码 JWT【英文标题】:How to encode JWT for APN tokenization (.NET, C#) 【发布时间】:2017-06-03 00:49:44 【问题描述】:我正在尝试通过标记化向 APN 发送推送通知。我尝试使用 jose-jwt 和 Microsot Jwt 类等一些库来创建 JWT 令牌,但我无法理解它。
我无法创建 JWT 并使用私钥对其进行签名。
为了与证书通信,我使用了 PushSharp,它工作得很好。任何人都可以帮助我使用类似的示例但使用令牌吗?
编辑:在此处遵循 Apple 的文档:https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html#//apple_ref/doc/uid/TP40008194-CH11-SW1
示例代码:我最接近的东西看起来像这样,但我不知道如何正确创建 CngKey
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);
【问题讨论】:
你能提供一些代码让我们看看吗?既然您问的是一般性问题,我建议您阅读以下内容:stormpath.com/blog/token-authentication-asp-net-core 谢谢,我会调查的。添加了一个代码示例,显示了我卡在哪里。 【参考方案1】:这是我使用的:
var privateKeyContent = System.IO.File.ReadAllText(AUTHKEYFILE);
var privateKey = privateKeyContent.Split('\n')[1];
var secretKeyFile = Convert.FromBase64String(privateKey);
var secretKey = CngKey.Import(secretKeyFile,CngKeyBlobFormat.Pkcs8PrivateBlob);
【讨论】:
感谢您的回答,已经有了解决方案。刚加了。也许你可以使用它。 运行您的代码我收到:'System.Core.dll 中发生'System.Security.Cryptography.CryptographicException' 类型的未处理异常' 这是p8 文件...有什么问题? 由于CngKey.Import
,这将无法在非 Windows 上运行【参考方案2】:
感谢您的回答,必须联系许多支持人员才能完成此操作。这是最终结果的样子。
/// <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);
【讨论】:
您能评论一下您为使其正常工作所做的工作吗?并说明您在哪里找到了所需的答案(如果不在此处)。 Jose-jwt 论坛和 Apple 支持。我缺少上面的 Base64 编码以使其正常工作。苹果人最终用他们的提示塑造了上面的代码。我在 C# 中找不到任何工作示例的官方文档。 关于您如何将通知实际发送到 Apple 服务器的任何提示?我已经尝试了很多事情来让它工作,但没有运气。如果您有任何代码,将不胜感激! @Brad C - 使用 HTTP/2 客户端 @user3790083 如何从 p8 文件中提取私钥?!谢谢!【参考方案3】:这是我使用的;
public static string getAppleJWT(string privateKeyPath, string teamId, string keyId)
var private_key = getPrivateKey(privateKeyPath);
var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var issueTime = DateTime.Now;
var payload = new Dictionary<string, object>()
"iss", teamId ,
"iat", (int)issueTime.Subtract(utc0).TotalSeconds
;
var headers = new Dictionary<string, object>()
"alg", "ES256",
"kid", keyId
;
return Jose.JWT.Encode(payload, private_key, JwsAlgorithm.ES256, headers);
public static CngKey getPrivateKey(string privateKeyPath)
var privateKeyLines = System.IO.File.ReadAllLines(privateKeyPath).ToList();
privateKeyLines.RemoveAt(privateKeyLines.Count - 1);
privateKeyLines.RemoveAt(0);
var privateKey = string.Join("", privateKeyLines);
var secretKeyFile = Convert.FromBase64String(privateKey);
var secretKey = CngKey.Import(secretKeyFile, CngKeyBlobFormat.Pkcs8PrivateBlob);
return secretKey;
【讨论】:
以上是关于如何为 APN 标记化(.NET、C#)编码 JWT的主要内容,如果未能解决你的问题,请参考以下文章
有关如何在 c# 中为 Windows 7 任务栏编码所需的信息
如何为 MSMQ 创建 C# 侦听器服务作为 Windows 服务
如何为 XSLT 代码片段配置 CruiseControl 的 C# 版本?