【问题标题】:Using ES256 algorithm with jwt-dotnet for Apple AppStore在 Apple AppStore 中使用 ES256 算法和 jwt-dotnet
【发布时间】:2022-07-24 03:44:45
【问题描述】:

我正在尝试生成一个jwt 令牌以连接到 AppStore API。我正在使用jwt-dotnet 库来执行此操作。

Apple 要求使用 ES256,而 jwt-dotnet 要求使用公钥来完成这项工作。我只从 AppStore 下载了一个私钥。我该如何处理?

这是我的代码:

public static string GenerateAppStoreJwtToken()
{
   var header = new Dictionary<string, object>()
   {
      { "kid", "MY_VALUE" },
      { "typ", "JWT" }
   };

   var scope = new string[1] { "GET /v1/apps?filter[platform]=IOS" };
   var payload = new Dictionary<string, object>
   {
      { "iss", "MY_VALUE" },
      { "iat", DateTimeOffset.UtcNow.ToUnixTimeSeconds() },
      { "exp", DateTimeOffset.UtcNow.AddMinutes(20).ToUnixTimeSeconds() },
      { "aud", "appstoreconnect-v1" },
      { "scope", scope }
   };


   IJwtAlgorithm algorithm = new ES256Algorithm(???); // What am I going to use here?
   IJsonSerializer serializer = new JsonNetSerializer();
   IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
   IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);

   var token = encoder.Encode(header, payload, privateKey);

   return token;
}

【问题讨论】:

  • 您可以从私钥生成公钥。但是你确定你有私人的吗?因为它通常不会在 API 场景中给出。
  • 我从 AppStore 下载了一个 p8 文件,该文件包含私钥。
  • 你应该能够生成一个公共的...在线检查工具

标签: c# jwt app-store


【解决方案1】:

这是对我有用的最终解决方案。我最终切换到jose-jwt,但我很确定你可以用jwt-dotnet 处理同样的事情。我刚刚发现使用jose-jwt 更容易一些。这是jose-jwt的链接:https://github.com/dvsekhvalnov/jose-jwt

这是最终代码。请注意,我确实使用了在p8 文件中找到的私钥,并且无需进行任何转换。所以我传递给GenerateAppStoreJwtToken()函数的privateKey参数直接来自p8文件。

using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using Jose;
    
public static string GenerateAppStoreJwtToken(string privateKey)
{
    var header = new Dictionary<string, object>()
    {
        { "alg", "ES256" },
        { "kid", "MY_VALUE" },
        { "typ", "JWT" }
    };
    
    var scope = new string[1] { "GET /v1/apps?filter[platform]=IOS" };
    var payload = new Dictionary<string, object>
    {
        { "iss", "MY_VALUE" },
        { "iat", DateTimeOffset.UtcNow.ToUnixTimeSeconds() },
        { "exp", DateTimeOffset.UtcNow.AddMinutes(15).ToUnixTimeSeconds() },
        { "aud", "appstoreconnect-v1" },
        { "scope", scope }
    };
    
    CngKey key = CngKey.Import(Convert.FromBase64String(privateKey), CngKeyBlobFormat.Pkcs8PrivateBlob);

    string token = JWT.Encode(payload, key, JwsAlgorithm.ES256, header);
 
    return token;
}

【讨论】:

    【解决方案2】:

    对于像我这样在其他地方使用 JWT-dotnet 因此不想使用其他 JWT 包的人来说,这很有效:

    • 通过删除页眉和页脚(“-----BEGIN PRIVATE KEY-----”等)并删除行尾字符以使单个字符串更易于存储来转换苹果私钥。

    • 从 Base64 转换并存储在 ReadOnlySpan 中

           ReadOnlySpan<byte> keyAsSpan = Convert.FromBase64String(key);
           var prvKey = ECDsa.Create();
           prvKey.ImportPkcs8PrivateKey(keyAsSpan,out var read);
      
    • 创建算法。需要一个空白的 ECDsa 实例来防止 NullException,但它不仅用于签署令牌,还需要验证哪些不是必需的。

            IJwtAlgorithm algorithm = new ES256Algorithm(ECDsa.Create(), prvKey)
      

    我能够使用这种方法收到来自苹果的回复令牌。

    【讨论】:

      猜你喜欢
      • 2021-05-31
      • 2022-11-30
      • 2021-08-16
      • 1970-01-01
      • 2019-10-30
      • 2020-05-17
      • 1970-01-01
      • 2020-03-31
      • 2020-11-27
      相关资源
      最近更新 更多