Go 封送员AppleID';s rsa的公钥。公钥
我正在尝试验证苹果在围棋中的JWT,我需要他们的公钥作为围棋来验证。我从中指定的端点检索了它们的密钥: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",
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还有更多的编码格式。这非常有帮助,谢谢。