【发布时间】:2015-09-20 15:01:40
【问题描述】:
我正在使用JWT。这就是我创建令牌的方式。
func createToken(user User) (string, error) {
token := jwt.New(jwt.GetSigningMethod("RS256"))
token.Claims["Name"] = user.Name
token.Claims["Email"] = user.Email
//token.Claims["ExpDate"] = time.Now().Add(time.Hour * 1).Unix()
tokenString, err := token.SignedString([]byte(config.PrivateKey))
if err != nil {
return "", err
}
return tokenString, nil
}
这就是我验证令牌的方式。
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte(config.PublicKey), nil
})
我用这个 python 代码生成了我的公钥和私钥
from Crypto.PublicKey import RSA
private = RSA.generate(1024)
public = private.publickey()
priv = private.exportKey()
pub = public.exportKey()
我收到crypto/rsa: verification error。当我打印解析的令牌时,一切看起来都很好,除了 token.Valid 是假的,token.Signature 是空的。
type Token struct {
Raw string // The raw token. Populated when you Parse a token
Method SigningMethod // The signing method used or to be used
Header map[string]interface{} // The first segment of the token
Claims map[string]interface{} // The second segment of the token
Signature string // The third segment of the token. Populated when you Parse a token
Valid bool // Is the token valid? Populated when you Parse/Verify a token
}
tokenString--> eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJFbWFpbCI6InRlc3RAaG90bWFpbC5jb20iLCJOYW1lIjoidGVzdE5hbWUifQ.fgd1h4LB1zzAiPFLKMOJrQu12rTLeXBDKHdnqiNc04NRn-1v7cHEQpDNawvScMIGrcQLbZo6WrldZQT9ImYWpUyy3CcD2uMO95I5PN6aXOSPb26nNGQpmIi1HNZrq5359hKZ6BWEJnW9iTg7RgmMvZGmIqlGLsOY2a6UiiwBsI0
token.Raw--> eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJFbWFpbCI6InRlc3RAaG90bWFpbC5jb20iLCJOYW1lIjoidGVzdE5hbWUifQ.fgd1h4LB1zzAiPFLKMOJrQu12rTLeXBDKHdnqiNc04NRn-1v7cHEQpDNawvScMIGrcQLbZo6WrldZQT9ImYWpUyy3CcD2uMO95I5PN6aXOSPb26nNGQpmIi1HNZrq5359hKZ6BWEJnW9iTg7RgmMvZGmIqlGLsOY2a6UiiwBsI0
token.Header--> map[alg:RS256 typ:JWT]
token.Claims--> map[Email:test@hotmail.com Name:testName]
token.Signature-->
token.Valid--> false
PS:我没有任何 SSL 证书。
【问题讨论】:
-
我强烈建议不要对 JSON Web 令牌使用 RSA(尤其是 1024 位密钥)。与仅使用
jwt.GetSigningMethod("HS256")(即 HMAC-SHA-256)相比,它确实没有提供实际的好处。 RSA 更容易出错。 -
@elithrar RSA vs HMAC ~ 公钥 vs 对称密钥;哪个更好取决于用例。 RSA 以何种方式“更容易出错”? JWT 库应该完成繁重的工作。
-
HMAC-SHA-256 很简单:你提供一个密钥,它会 MAC 化它。 RSA 更依赖于密钥强度(1024 不会削减它),最近的许多 JWT 漏洞都与 RSA 密钥有关,并且它增加了更多的复杂性(解析证书/私钥。除非您对客户端有一些迫切需要用你的公钥自我验证令牌,几乎没有什么收获。
-
@elithrar 有些用例需要与客户端验证令牌无关的公钥算法,例如依赖方为第三方的情况下。您不能向第三方提供您的 HMAC 机密。提问者没有说明他们生成的令牌是如何使用的。
-
很清楚。我想说的是“如果您必须询问如何生成 RSA 密钥并将它们与 SSL 混为一谈,那么您很可能不需要使用 RSA 密钥。”这些用例通常定义明确(正如您所指出的)。带有 React 或 Angular 的 SPA 的 JWT 不需要 RSA 签名的 JWT。