Пакет Golang jwt-go с ключом rsa. Как поставить публичный ключ и как его получить из токена?

Я пытаюсь сгенерировать токен с ключом rsa, используя пакет jwt-go в golang.

Здесь есть блог, объясняющий, как сделать это, но этот код всегда будет проверять все токены, потому что он использует открытый ключ, хранящийся на сервере, и не получает его из токена. Как поместить полный открытый ключ в токен? Я пытался это:

var secretKey, _ = rsa.GenerateKey(rand.Reader, 1024)
token := jwt.New(jwt.SigningMethodRS256)
token.Claims["username"] = "victorsamuelmd"
token.Claims["N"] = secretKey.PublicKey.N
token.Claims["E"] = secretKey.PublicKey.E

tokenString, err := token.SignedString(secretKey)

nt, err := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) {
    // here I need to recover the public key from the token
    // but N is a big.Int and the token stores N as int64
})

Извините за мой английский. Спасибо.


person victorsamuelmd    schedule 20.03.2015    source источник
comment
Пример в блоге неполный. Когда он вызывает jwt.ParseFromRequest, он действительно проверяет совпадение подписей. Вы хотите использовать JWT для аутентификации подписи с симметричным ключом? Если вы это сделаете, то в KeyFunc, переданном в jwt.ParseFromRequest, вы должны извлечь открытый ключ из утверждений. Найдите закрытый ключ в своем хранилище данных. Воссоздайте подпись, а затем сравните ее с подписью в jwt.   -  person icchanobot    schedule 20.03.2015
comment
Нет, мне нужна асимметричная ключевая подпись с использованием пакета crypto/rsa от go.   -  person victorsamuelmd    schedule 20.03.2015
comment
о, хорошо .. тогда я больше не думаю, что это строго jwt .. но вам нужно помнить, что претензии отправляются внутри json, т. е. на самом деле они не хранятся как int64 .. они просто анализируются как int64, так что вы, вероятно, можете просто привести его   -  person icchanobot    schedule 22.03.2015


Ответы (1)


Я думаю, что хранение открытого ключа в утверждениях — не очень хорошая идея, потому что мы можем технически проверить JWT с помощью этого ключа, но это означает, что это больше не подписанный JWT. Если кто-то может сгенерировать JWT со своим закрытым ключом и сохранить открытый ключ в JWT, мы не можем быть уверены, кто является подписантом.

В любом случае, вы можете преобразовать открытый ключ в формат PEM, который представляет собой просто строку, и сохранить его в утверждениях. На стороне клиента вы также можете просто снова проанализировать его в формате открытого ключа. Пример кода ниже:

privateKey, _ := rsa.GenerateKey(rand.Reader, 1024)
bytes, _ := x509.MarshalPKIXPublicKey(&privateKey.PublicKey)
pem := pem.EncodeToMemory(&pem.Block{
    Type:  "RSA PUBLIC KEY",
    Bytes: bytes,
})
claim["publickey"] = string(pem)

и

pem := []byte(claims["publickey"].(string))
return jwt.ParseRSAPublicKeyFromPEM(pem)

jwt — это jwt-go dgrijalva.

person sio4    schedule 27.07.2017
comment
Не всегда. Широко распространена практика размещения открытого ключа в качестве заголовка или утверждения внутри токена jwt. Службе валидации нужно валидировать эмитента или использовать, например, с помощью CA center. Хорошим примером этого является протокол STIR/SHAKEN PASSport, который используется при любом телефонном звонке в США. - person kkost; 17.06.2021