2015-06-20 50 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,那意味着我需要將私鑰放在微服務和客戶端應用程序中?那不會是一個嚴重的安全漏洞?