首页 > 解决方案 > 为 Apple 的 DeviceCheck API 生成 JWT

问题描述

我正在尝试使用 Apple 的 DeviceCheck API。我似乎无法制作一个不会失败的请求,因为401 Unable to verify authorization token我尝试了一些小的变化。

import java.security.KeyFactory
import java.security.spec.PKCS8EncodedKeySpec
import java.util.Base64

import io.jsonwebtoken.{Jwts, SignatureAlgorithm}

val deviceCheckPrivateKey = "<Key in plaintext without the key-guards>"
val privateKey = KeyFactory.getInstance("EC").generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder.decode(deviceCheckPrivateKey)))

val builder = Jwts
  .builder()
  .setHeaderParam("kid", "<key-id-from-file>")
  .signWith(SignatureAlgorithm.ES256, privateKey)
  .claim("iss", "<team-id>")
  .claim("iat", System.currentTimeMillis())

println(builder.compact())

我把这个暂存文件的输出插入到这里:

curl -i -H "Authorization: Bearer <Output>" -X POST --data-binary @ValidQueryRequest.json https://api.development.devicecheck.apple.com/v1/query_two_bits 

按照Apple 文档的建议。

这个整体结构对吗?我正在尝试遵循本教程,这意味着这种结构:

JWT 签名流程概述

但苹果的这句话:

您发送到查询和更新端点的每个请求都必须包含一个包含您的身份验证密钥的授权标头。身份验证密钥必须使用 ES256 算法并采用 Base 64 URL 编码的 JSON Web 令牌格式。如果您的令牌不使用此格式,您会收到 BAD_AUTHENTICATION_TOKEN HTTP 错误。

建议我的请求应该“包含我的身份验证密钥”,而不是使用密钥签名。

标签: iosscalajwtjjwtdevicecheck

解决方案


根据:https ://www.rfc-editor.org/rfc/rfc7519#section-4.1.6

val builder = Jwts
  .builder()
  .setHeaderParam("kid", "<key-id-from-file>")
  .signWith(SignatureAlgorithm.ES256, privateKey)
  .claim("iss", "<team-id>")
  .claim("iat", System.currentTimeMillis()) // <--- Should be seconds, not milliseconds

推荐阅读