【问题标题】:Confusion relating to public and private keys and JWT与公钥和私钥以及 JWT 相关的混淆
【发布时间】:2026-02-12 13:30:01
【问题描述】:

我正在 Go Web 服务中试用 JWT(JSON Web 令牌)。这是我到目前为止所做的:

package jwt

import(
    "fmt"
    "net/http"
    "github.com/gorilla/mux"
    "github.com/dgrijalva/jwt-go"
    "io/ioutil"
)

var privateKey []byte
var publicKey []byte 

func JSONWebTokensHandler(w http.ResponseWriter, r * http.Request){

    // Create the token
    encodeToken := jwt.New(jwt.SigningMethodHS256)
    // Set some claims
    encodeToken.Claims["Latitude"] = "25.000"
    encodeToken.Claims["Longitude"] = "27.000"
    // Sign and get the complete encoded token as a string
    tokenString, err := encodeToken.SignedString(privateKey)

    decodeToken, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {

        if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
            return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
        }

        return publicKey,nil
    })

    if decodeToken.Valid {

        fmt.Fprintf(w,"Lat:  %s, Lng: %s",decodeToken.Claims["Latitude"],decodeToken.Claims["Longitude"])

    }  else {

        fmt.Fprintf(w,"Couldn't handle this token: %s", err)

    }

}

func init(){

    privateKey,_ = ioutil.ReadFile("demo.rsa")
    publicKey,_ = ioutil.ReadFile("demo.rsa.pub")

    r := mux.NewRouter()
    r.HandleFunc("/jwt",JSONWebTokensHandler).Methods("GET")
    http.Handle("/", r)

}

现在,如果我的理解是正确的,使用私钥编码的令牌可以使用公钥解码。这就是我在上面的代码中假设的,但是当我运行代码时,我得到了错误:

无法处理此令牌:签名无效

如果我使用相同的密钥进行编码和解码,那么代码可以工作。

我想知道的是,我的理解或代码中是否有问题?

【问题讨论】:

    标签: go google-app-engine jwt jwt-go


    【解决方案1】:

    JWT 未使用 RSA 等非对称密码进行签名。它使用HMAC,它使用单个密钥。实际上,这里的重点不是向其他人证明您签署了令牌。这是为了向自己证明你已经签署了它,从而禁止任何没有你的密钥的人修改令牌。

    【讨论】:

    • 正确,尽管 RSA 算法是 JWT“标准”的一部分并包含在 jwt-go 包中。但是,我强烈反对他们:从实现的角度来看,HMAC 结构更容易“正确”,并且仍然提供所需的功能:防止第三方修改令牌。
    • @elithrar 谢谢。我将答案编辑为“The”JWT 而不是“A”JWT。发布的代码使用 HMAC。
    【解决方案2】:

    您正在使用jwt.SigningMethodHMAC. 因此,您正在使用 HMAC 进行签名,签名是由对称密钥(秘密)加密的令牌。

    您应使用:jwt.New(jwt.SigningMethodRS256) 使用非对称密钥对进行签名。

    【讨论】:

      【解决方案3】:

      非常有趣,因为我有类似的问题,当我有微服务和客户端应用程序需要验证来自另一个内部服务器的令牌时,所以如果你建议使用 HMAC 而不是 RSA,这意味着我需要将私钥放在微服务和客户端应用程序中?这不会是一个严重的安全漏洞吗?

      【讨论】: