Как проверить токен JWE в Golang

У меня есть 2 вопроса, но сначала я хочу предоставить некоторый контекст:

В нашем веб-приложении мы используем NextAuth для создания токенов jwt, которые затем прикрепляем к запросам на наш сервер Golang (для получения ресурсов).

Сгенерированные токены кажутся токенами JWE, сгенерированными через A256GCM. На нашем сервере golang мы хотим проверить токен и извлечь из него несколько пользовательских утверждений. Тем не менее, мы изо всех сил пытаемся найти способ сделать расшифровку. Мы используем go-jose следующим образом:

rawToken := `eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..aiIqD7-cU8Hu92F8.Kx2k99cyLYJR1P0xK_1wUsVO521T7kYSKx-OEutVJcpzbX27hZH0kh2MlBLxQHdmc8q4uXglhjl4JE3nTp_c6nOjga-faHyxYqKrZGJFLlu9MC4JVUWyonX6doFq0gl3UX9ABtP2t35Qly-w1qKH8BdG9x4iB1YM-yvs1w-HpBbMFQR7U7X4oHWIh_YJQlWADesYq6da7A97GSSXs2Go6yb7SH5WWd7iQzDu-UO6eg._PqujCUyMUqOkID80vJiDw`
key := []byte("thisisaverylongtextusedforhashing")

enc, err := jwt.ParseEncrypted(rawToken)
if err != nil {
    panic(err)
}

out := jwt.Claims{}
if err := enc.Claims(key, &out); err != nil {
    panic(err)
}
fmt.Printf("iss: %s, sub: %s\n", out.Issuer, out.Subject)

Мы получаем: panic: square/go-jose: error in cryptographic primitive

PS: секрет я передаю nextAuth, используемому для генерации JWE: thisisaverylongtextusedforhashing

Необработанный токен JWE, который выводит NextAuth и который я хочу проверить на своем сервере golang: eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..aiIqD7-cU8Hu92F8.Kx2k99cyLYJR1P0xK_1wUsVO521T7kYSKx-OEutVJcpzbX27hZH0kh2MlBLxQHdmc8q4uXglhjl4JE3nTp_c6nOjga-faHyxYqKrZGJFLlu9MC4JVUWyonX6doFq0gl3UX9ABtP2t35Qly-w1qKH8BdG9x4iB1YM-yvs1w-HpBbMFQR7U7X4oHWIh_YJQlWADesYq6da7A97GSSXs2Go6yb7SH5WWd7iQzDu-UO6eg._PqujCUyMUqOkID80vJiDw.

Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
2
0
296
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Учитывая ваш вклад, я составил ответ, который может помочь вам с вашей проблемой. Во-первых, я использовал версию 2 пакета gopkg.in/go-jose/go-jose.v2, потому что (из того, что я видел) алгоритм A256GCM не полностью совместим с самой новой версией пакета, которая должна быть версией 3. Ниже вы можете найти соответствующий код:

package main

import (
    "crypto/rand"
    "crypto/rsa"
    "fmt"
    "io"
    "os"
    "time"

    "github.com/golang-jwt/jwt"
    jose_jwt "gopkg.in/go-jose/go-jose.v2"
)

type CustomClaims struct {
    Username string `json:"username"`
    Password string `json:"password"`
    jwt.StandardClaims
}

func main() {
    privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
    if err != nil {
        panic(err)
    }

    // generate token
    token, err := generateToken()
    if err != nil {
        panic(err)
    }

    publicKey := &privateKey.PublicKey
    encrypter, err := jose_jwt.NewEncrypter(jose_jwt.A256GCM, jose_jwt.Recipient{
        Algorithm: jose_jwt.RSA_OAEP_256,
        Key:       publicKey,
    }, nil)
    if err != nil {
        panic(err)
    }

    plainText := []byte(token)
    object, err := encrypter.Encrypt(plainText)
    if err != nil {
        panic(err)
    }

    serialized := object.FullSerialize()

    object, err = jose_jwt.ParseEncrypted(serialized)
    if err != nil {
        panic(err)
    }

    decrypted, err := object.Decrypt(privateKey)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(decrypted))

    // parse token
    claims, err := ValidateToken(string(decrypted))
    if err != nil {
        panic(err)
    }

    fmt.Println(len(claims))
}

Здесь мы сначала генерируем закрытый ключ для шифрования токена, а затем расшифровываем его с помощью открытого ключа. Для краткости я опустил код, используемый для создания и проверки токена JWT. Чтобы протестировать решение, я добавил два пользовательских утверждения к сгенерированному токену (username и password, которые определены в структуре CustomClaims). Затем, когда мы проанализируем токен, мы сможем получить их значения.
Дайте мне знать, если это поможет вам!

Спасибо! В NextAuth (где генерируется jwe) мы предоставляем указанный выше секрет (данный тест). Я не думаю, что у нас есть доступ к какому-либо PK для использования здесь алгоритма. Я дал наш точный секрет + вывод jwe для справки

Martin 28.11.2022 11:27

Можете ли вы предоставить все соответствующие файлы? С еще и разделом импорта и так далее? Так что я уверен в том, что вы использовали.

ossan 28.11.2022 11:33

Для NextAuth (nextjs) или проверки нашего токена golang?

Martin 28.11.2022 12:01

Если вы можете предоставить все, чтобы я мог воспроизвести все с нуля, спасибо!

ossan 28.11.2022 12:08
goplay.tools/snippet/FsiIc2Uw_12 вот точная расшифровка, опять же, токен генерируется нашим сервером авторизации (через nextauth) с предоставленным секретом
Martin 28.11.2022 12:13

Другие вопросы по теме