You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Go中暴露JWK端点时模数生成有误,求排查问题原因

在Go中暴露JWK端点时模数生成错误的问题排查

我尝试在Go中暴露JWK端点,但生成模数的方式似乎不正确,请问我哪里出错了?

密钥生成步骤

openssl genrsa -out private_key.pem 2048

公钥生成命令:

openssl rsa -in private_key.pem -pubout -out public_key.pub

Go程序实现

公钥读取与编码部分

var verifyKey *rsa.PublicKey
verifyBytes, err := ioutil.ReadFile("public_key.pub")
verifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyBytes)

modulus := base64.StdEncoding.EncodeToString((*verifyKey.N).Bytes())
exponent := base64.StdEncoding.EncodeToString(big.NewInt(int64(verifyKey.E)).Bytes())

JWK端点处理代码

func (s *ExtAuthzServer) ServeHTTP(response http.ResponseWriter, request *http.Request) {
    if request.URL.Path == "/.well-known/jwks.json" {
        log.Printf("[HTTP] jwks requested")
        n := base64.StdEncoding.EncodeToString((*verifyKey.N).Bytes())
        e := base64.StdEncoding.EncodeToString(big.NewInt(int64(verifyKey.E)).Bytes())
        keys := PublicKeysData{
            Keys: []KeyData{KeyData{"RSA", "go-ext-authz", "sig", n, e}},
        }
        response.WriteHeader(http.StatusOK)
        b, _ := json.Marshal(keys)
        _, _ = response.Write([]byte(b))
        return
    }
}

结构体定义

type PublicKeysData struct {
    Keys []KeyData `json:"keys"`
}

type KeyData struct {
    Kty string `json:"kty"`
    Kid string `json:"kid"`
    Use string `json:"use"`
    N   string `json:"n"`
    E   string `json:"e"`
}

请求端点后的输出

HTTP/1.1 200 OK
Content-Length: 419
Content-Type: text/plain; charset=utf-8
Date: Fri, 06 Jan 2023 16:35:48 GMT

{
    "keys": [
        {
            "e": "AQAB",
            "kid": "go-ext-authz",
            "kty": "RSA",
            "n": "pulIwmeoYdXIOS+vPMURqJsB2IhL3G+OIgMm8I7FqwgeM1Rf12kxycb8VbAVgaN+cMsVfFzxg+oiUqHW4af6dO503bNgZ88DemO/gT9J9Ob4EcmNNohVX28ts6qRmhOtTN0o4xV3cHXiJYL+JTf3U/GhyEK8bJcIgj1X8kNhl7X3gtza2Ft5S8t61ZepdQJdDIdzq7wpw2DTRJ76rvstOvzvLNjfhPhX48aFaw0tSJKw2LmoawHvUviP6tjro7gFUmLX6xolniv/1U/Uas8ZbNFPZBbUs1mjMccNErtUi02VZuHWqGtHL8v+n7rgso9NMd/ljU+BV/dB2KWnO6dD2Q==",
            "use": "sig"
        }
    ]
}

问题排查与修正

问题出在Base64编码格式不符合JWK规范:JWK要求使用Base64URL无填充编码,而你当前使用的是标准Base64编码。

具体修正点

  1. 将所有base64.StdEncoding替换为base64.RawURLEncoding,该编码会自动替换标准Base64中的+、/为-、_,并省略末尾的填充=,完全符合JWK的格式要求。
  2. 对模数N和指数E的编码都需要做此替换。

修正后的代码示例

// 公钥读取部分的修正
modulus := base64.RawURLEncoding.EncodeToString((*verifyKey.N).Bytes())
exponent := base64.RawURLEncoding.EncodeToString(big.NewInt(int64(verifyKey.E)).Bytes())

// 端点处理部分的修正
n := base64.RawURLEncoding.EncodeToString((*verifyKey.N).Bytes())
e := base64.RawURLEncoding.EncodeToString(big.NewInt(int64(verifyKey.E)).Bytes())

补充说明

标准Base64的特殊字符在URL中需要转义,而JWK规范明确要求使用Base64URL无填充格式,避免转义问题,确保客户端能正确解析JWKS内容。

内容的提问来源于stack exchange,提问作者Marc06210

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 02:01:04