go - 如何使用 jwt golang 包通过 ECDSA 方法签署 JWT - Sign in with Apple

标签 go jwt ecdsa

在与 Apple 集成登录时,您会在您的 Apple 开发者帐户中生成一个 key 。
这是一个名为 AuthKey_3JMD5K6.p8 的文件看起来像

-----BEGIN PRIVATE KEY-----
MasdfjalskdasdflaASDFAadsflkjaADSFAewfljasdfljkasefasdflkjasdf
asdfljkasdfASDFASDFoiqretasdoiyjlfsbgREtaREGSDFBREtafsrgAREGfdsgaregR
LKJIOEWFNLasdflkawefjoiasdflk
-----END PRIVATE KEY-----
所以我做了一个var appleKey := MasdfjalskdasdflaASDFAadsflkjaADSFAewfljasdfljkasefasdflkjasdf asdfljkasdfASDFASDFoiqretasdoiyjlfsbgREtaREGSDFBREtafsrgAREGfdsgaregRLKJIOEWFNLasdflkawefjoiasdflk我之前使用 HMAC-SHA 方法签署了 jwt,这相当简单,但我不知道如何使用 ECDSA 方法签署 jwt。
我以与 HMAC-SHA 方法相同的方式编写代码,但出现错误 key is of invalid type那么使用 golang 的 jwt 库如何使用 ECDSA 方法签署我的 jwt?
我的代码
  // generate client secret jwt using apple key
  expirationTime := time.Now().Add(5 * time.Minute)
  claims := &Claims{
    StandardClaims: jwt.StandardClaims {
      Audience: "https://appleid.apple.com",
      Subject: "com.app.ios",
      Issuer: string(appleTeamId),
      ExpiresAt: expirationTime.Unix(),
      IssuedAt: time.Now().Unix(),
    },
  }
  appleToken := jwt.NewWithClaims(jwt.SigningMethodES256, claims)
  appleToken.Header["kid"] = appleKid

  signedAppleToken, err := appleToken.SignedString(appleKey)
我现在知道这不是你的做法,它比这更复杂一些,但这样做的方法是什么?
我发现这篇文章告诉您如何手动执行此操作:
http://p.agnihotry.com/post/validating_sign_in_with_apple_authorization_code/
但是我已经将 jwt 库用于 golang 用于 token 的另一部分:
https://godoc.org/github.com/dgrijalva/jwt-go

最佳答案

github.com/dgrijalva/jwt-goSigningMethodECDSA.Sign docs你可以找到:

[...] For this signing method, key must be an ecdsa.PrivateKey struct


所以,举个例子:
    p8bytes, err := ioutil.ReadFile("SomeAppleKey.p8")
    if err != nil {
      log.Println(err)
      return
    }

    // Here you need to decode the Apple private key, which is in pem format
    block, _ := pem.Decode(p8bytes)
    // Check if it's a private key
    if block == nil || block.Type != "PRIVATE KEY" {
      log.Println("Failed to decode PEM block containing private key")
      return
    }
    // Get the encoded bytes
    x509Encoded := block.Bytes

    token := jwt.NewWithClaims(
        jwt.SigningMethodES256, // specific instance of `*SigningMethodECDSA`
        jwt.StandardClaims{
            // ...
        },
    )

    // Now you need an instance of *ecdsa.PrivateKey
    parsedKey, err := x509.ParsePKCS8PrivateKey(x509Encoded) // EDIT to x509Encoded from p8bytes
    if err != nil {
        panic(err)
    }

    ecdsaPrivateKey, ok := parsedKey.(*ecdsa.PrivateKey)
    if !ok {
        panic("not ecdsa private key")
    }

    // Finally sign the token with the value of type *ecdsa.PrivateKey
    signed, err := token.SignedString(ecdsaPrivateKey)
    if err != nil {
        panic(err)
    }
    fmt.Println(signed) // the signed JWT

注意:如代码片段所示,因为来自苹果的 key 文件是PEM格式,需要先解码

警告!
请注意 github.com/dgrijalva/jwt-go长期无人维护,有未修复的严重错误 .并且在版本 4 之前不支持 Go 模块(无论如何这只是一个预览版)。我强烈建议选择一个不同的库来处理 JWT。
2021 年 6 月更新
该库现在有一个官方社区分支: golang-jwt/jwt blessed由原始项目的所有者。

关于go - 如何使用 jwt golang 包通过 ECDSA 方法签署 JWT - Sign in with Apple,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63260599/

相关文章:

go - 如何将 ECDSA 公钥转换为 PEM 文件

javascript - Wordpress 上带有授权 header (CORS) 的 HTTP 发布

cryptography - Golang 使用 ecdsa 和来自 SHA224 摘要的私钥进行签名

mongodb - 如何在使用 go 从 mongodb 获取数据时对数据进行分组?

rest - 使用 Go 向本地主机服务器发出 GET http 请求时的空响应

java - 如何检查电子邮件是否存在,除了请求的用户之外?

ruby - 使用 pem 证书解码 ruby​​/jwt

android - 如何生成 33 字节压缩的 NIST P-256 公钥?

json - 我如何使用 Go 漂亮地打印 JSON?

go - 如何使用golang和数组数据创建json数据