gpt4 book ai didi

go - Marshal AppleID 的公钥到 rsa.PublicKey

转载 作者:行者123 更新时间:2023-12-03 10:09:07 24 4
gpt4 key购买 nike

我正在尝试在 Go 中验证来自 Apple 的 JWT,我需要他们的公钥作为 Go 的 rsa.PublicKey 这样做。我从以下指定的端点检索了他们的 key :

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 时遇到错误.
然后我注意到 key 包含 "n""e"字符串对,并且定义为 here所以我尝试直接创建公钥。但是, NErsa.PublicKey*big.Intint分别。
我似乎找不到 "n" 的编码和 "e" ,所以我无法准确地将值转换为 rsa.PublicKey .我试过base64,但是没有用。
谁能告诉我如何将 Apple 的公钥转换为合适的 rsa.PublicKey请?

最佳答案

"n" 的值和 "e"在你的 JSON 中只是 base64 编码的大端二进制整数,所以一旦你解码它们,你可以将它们转换为类型 *big.Intbig.Int.SetBytes ,然后使用这些来填充 *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.
}

关于go - Marshal AppleID 的公钥到 rsa.PublicKey,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66067321/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com