Go 封送员AppleID';s rsa的公钥。公钥

Go 封送员AppleID';s rsa的公钥。公钥,go,oauth-2.0,jwt,rsa,Go,Oauth 2.0,Jwt,Rsa,我正在尝试验证苹果在围棋中的JWT,我需要他们的公钥作为围棋来验证。我从中指定的端点检索了它们的密钥: https://developer.apple.com/documentation/sign_in_with_apple/fetch_apple_s_public_key_for_verifying_token_signature 并得到以下结果: { "keys": [ { "kty": "RSA",

我正在尝试验证苹果在围棋中的JWT,我需要他们的公钥作为围棋来验证。我从中指定的端点检索了它们的密钥:

https://developer.apple.com/documentation/sign_in_with_apple/fetch_apple_s_public_key_for_verifying_token_signature
并得到以下结果:

{
  "keys": [
    {
      "kty": "RSA",
      "kid": "86D88Kf",
      "use": "sig",
      "alg": "RS256",
      "n": "iGaLqP6y-SJCCBq5Hv6pGDbG_SQ11MNjH7rWHcCFYz4hGwHC4lcSurTlV8u3avoVNM8jXevG1Iu1SY11qInqUvjJur--hghr1b56OPJu6H1iKulSxGjEIyDP6c5BdE1uwprYyr4IO9th8fOwCPygjLFrh44XEGbDIFeImwvBAGOhmMB2AD1n1KviyNsH0bEB7phQtiLk-ILjv1bORSRl8AK677-1T8isGfHKXGZ_ZGtStDe7Lu0Ihp8zoUt59kx2o9uWpROkzF56ypresiIl4WprClRCjz8x6cPZXU2qNWhu71TQvUFwvIvbkE1oYaJMb0jcOTmBRZA2QuYw-zHLwQ",
      "e": "AQAB"
    },
    {
      "kty": "RSA",
      "kid": "eXaunmL",
      "use": "sig",
      "alg": "RS256",
      "n": "4dGQ7bQK8LgILOdLsYzfZjkEAoQeVC_aqyc8GC6RX7dq_KvRAQAWPvkam8VQv4GK5T4ogklEKEvj5ISBamdDNq1n52TpxQwI2EqxSk7I9fKPKhRt4F8-2yETlYvye-2s6NeWJim0KBtOVrk0gWvEDgd6WOqJl_yt5WBISvILNyVg1qAAM8JeX6dRPosahRVDjA52G2X-Tip84wqwyRpUlq2ybzcLh3zyhCitBOebiRWDQfG26EH9lTlJhll-p_Dg8vAXxJLIJ4SNLcqgFeZe4OfHLgdzMvxXZJnPp_VgmkcpUdRotazKZumj6dBPcXI_XID4Z4Z3OM1KrZPJNdUhxw",
      "e": "AQAB"
    }
  ]
}
我尝试了
x509.ParsePKCS1PublicKey(…)
函数,通过使用
asn1.Marshall(…)
函数解析返回的单个键和整个JSON。我试图分析
der
时出错

然后,我注意到该键包含
“n”
“e”
字符串对,它们是被定义的,因此我尝试直接创建公钥。但是,
rsa.PublicKey
中的
N
E
分别是
*big.Int
Int

我似乎找不到
“n”
“e”
的编码,因此无法准确地将值转换为
rsa.PublicKey
。我试过base64,但没用

有谁能告诉我如何将苹果的公钥转换成合适的rsa.PublicKey吗?

JSON中的
“n”
“e”
的值都是base64编码的大端二进制整数,所以一旦你解码了它们,你就可以用
big.Int.SetBytes将它们转换成类型
*big.Int
,然后使用它们填充
*rsa.PublicKey

您提到您尝试了base64,但它不起作用,但您需要确保使用正确的编码和填充选项-编码字符串中出现
-
-
字符表示您正在处理RFC 4648 URL安全编码,字符串长度不能被4整除这一事实表明不存在填充字符,因此
base64.URLEncoding.WithPadding(base64.NoPadding)
是您需要使用的

您可以直接解组并转换为的类型的综合示例:

package main

import (
        "crypto/rsa"
        "encoding/base64"
        "encoding/json"
        "log"
        "math/big"
)

const keyJSON = `{
    "kty": "RSA",
    "kid": "86D88Kf",
    "use": "sig",
    "alg": "RS256",
    "n": "4dGQ7bQK8LgILOdLsYzfZjkEAoQeVC_aqyc8GC6RX7dq_KvRAQAWPvkam8VQv4GK5T4ogklEKEvj5ISBamdDNq1n52TpxQwI2EqxSk7I9fKPKhRt4F8-2yETlYvye-2s6NeWJim0KBtOVrk0gWvEDgd6WOqJl_yt5WBISvILNyVg1qAAM8JeX6dRPosahRVDjA52G2X-Tip84wqwyRpUlq2ybzcLh3zyhCitBOebiRWDQfG26EH9lTlJhll-p_Dg8vAXxJLIJ4SNLcqgFeZe4OfHLgdzMvxXZJnPp_VgmkcpUdRotazKZumj6dBPcXI_XID4Z4Z3OM1KrZPJNdUhxw",
    "e": "AQAB"
}`

// decodeBase64BigInt decodes a base64-encoded larger integer from Apple's key format.
func decodeBase64BigInt(s string) *big.Int {
        buffer, err := base64.URLEncoding.WithPadding(base64.NoPadding).DecodeString(s)
        if err != nil {
                log.Fatalf("failed to decode base64: %v", err)
        }

        return big.NewInt(0).SetBytes(buffer)
}

// appleKey is a type of public key.
type appleKey struct {
        KTY string
        KID string
        Use string
        Alg string
        N   *big.Int
        E   int
}

// UnmarshalJSON parses a JSON-encoded value and stores the result in the object.
func (k *appleKey) UnmarshalJSON(b []byte) error {
        var tmp struct {
                KTY string `json:"kty"`
                KID string `json:"kid"`
                Use string `json:"use"`
                Alg string `json:"alg"`
                N   string `json:"n"`
                E   string `json:"e"`
        }

        if err := json.Unmarshal(b, &tmp); err != nil {
                return err
        }

        *k = appleKey{
                KTY: tmp.KTY,
                KID: tmp.KID,
                Use: tmp.Use,
                Alg: tmp.Alg,
                N:   decodeBase64BigInt(tmp.N),
                E:   int(decodeBase64BigInt(tmp.E).Int64()),
        }

        return nil
}

// RSA returns a corresponding *rsa.PublicKey
func (k appleKey) RSA() *rsa.PublicKey {
        return &rsa.PublicKey{
                N: k.N,
                E: k.E,
        }
}

func main() {
        // Decode the Apple key.
        var ak appleKey
        if err := json.Unmarshal([]byte(keyJSON), &ak); err != nil {
                log.Fatalf("failed to unmarshal JSON: %v", err)
        }

        // Convert it to a normal *rsa.PublicKey.
        rk := ak.RSA()

        if rk.Size() != 256 {
                log.Fatalf("unexpected key size: %d", rk.Size())
        }

        // Do what you like with the RSA key now.
}

我不知道base64还有更多的编码格式。这非常有帮助,谢谢。