2015-06-20 80 views
1

我正在尝试使用Go Web服务中的JWT(JSON Web令牌)。这是我到目前为止已经完成:与公钥和私钥以及JWT有关的混淆

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) 

} 

现在,如果我的理解是正确的,即使用私有密钥加密令牌可以使用公共密钥解码。这就是我在代码中已经假设上述然而,当我运行代码我得到的错误:

Couldn't handle this token: signature is invalid

如果我使用相同的密钥编码和解码,然后代码工作。

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

回答

3

JWT未使用非对称密码(如RSA)进行签名。它使用一个HMAC,它使用一个单一的密钥。事实上,这里的重点不是向别人证明你签署了令牌。这是为了向你自己证明你签署了它,并因此禁止任何没有你的密钥修改令牌的人。

+1

正确,尽管RSA算法是JWT“标准”的一部分,并且包含在jwt-go包中。但是,我会强烈建议他们:HMAC构建从实现的角度来看更容易'正确',并且仍然提供所需的功能:防止第三方修改令牌。 – elithrar

+0

@elithrar谢谢。我编辑答案来说“JWT”而不是“A”JWT。发布的代码使用HMAC。 –

1

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

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

0

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