Расшифровка токена JWE в голанге

У меня такая проблема, я создал JWE в node.js с помощью node-jose следующим образом:

const keystore = [
  {
    kty: 'oct',
    kid: 'QLdRkgyMx_po0fPo5XnOzQQB4iTcyay36m_PA62SBiw',
    k: 'A-OAikjssQZeLkj8N_2Xb9qPBG6lSq10YeLbiTF-kQuM_qKy08jwFqQwsLzn9fmNPkayM9uRg1lHBrPoK_fGtQ'
  }
]

const ks = await jose.JWK.asKeyStore(keystore);
const rawKey = ks.get(keystore[0].kid)
const key = await jose.JWK.asKey(rawKey);
const jwe = await jose.JWE
      .createEncrypt({format: 'compact'}, key)
      .update(payload)
      .final();

Согласно документации создается с помощью "alg": "PBES2-HS256+A128KW", "enc": "A128CBC-HS256", и если я проверю это в jwt.io, это так.

Затем мне нужно расшифровать в golang, поэтому мне нравится это с помощью go-jose.v2:

package main

import (
    "fmt"
    "gopkg.in/square/go-jose.v2"
)

const jweRaw string = "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoiUUxkUmtneU14X3BvMGZQbzVYbk96UVFCNGlUY3lheTM2bV9QQTYyU0JpdyIsInAyYyI6ODE5MiwicDJzIjoiaVktZEdKaWtYbUZCdXMwRFp5eHdIQSJ9.QkuIGmPojLDX-wpTVTjZRnA093fJRVM6OHkpmoQeyLubahOABg62WQ.z6dm86nWHcWgzmPXiuk0kg.7mOgYF6d9hgfXtTj9RUv7BNuYH-jBAs8px0boOFj1mke_JPetIT44yY7ceffFRfS2QYc6RQMtTvb7vdMArkqeB483g3-tcoCGWxafOb0VfVQHrPTdjpGMLF-9uIJw9z5.RA0Dn-B_Y3kvXYRvVTiNFQ"
const kid string = "QLdRkgyMx_po0fPo5XnOzQQB4iTcyay36m_PA62SBiw"
const k string = "A-OAikjssQZeLkj8N_2Xb9qPBG6lSq10YeLbiTF-kQuM_qKy08jwFqQwsLzn9fmNPkayM9uRg1lHBrPoK_fGtQ"

func main() {
    jwe, err1 := jose.ParseEncrypted(jweRaw)
    if err1 != nil {
        panic(err1)
    }
    fmt.Println("jwe", jwe)
    bytes, err2 := jwe.Decrypt(jose.JSONWebKey{Algorithm: "PBES2-HS256+A128KW", Use: "A128CBC-HS256", KeyID: kid, Key: k})
    if err2 != nil {
        panic(err2)
    }
    fmt.Println("bytes", string(bytes))
}

Но это вызывает панику "panic: square/go-jose: error in cryptographic primitive". Вы можете проверить это здесь: https://play.golang.org/p/qB3QNtGwBsK

Я уже пробовал с https://github.com/lestrrat-go/jwx, но он не поддерживает алгоритм PBES2-HS256+A128KW

Спасибо.

ОБНОВЛЕНИЕ: вот дополнительная информация:

Их ключ в узле был создан следующим образом:

const keystore = await jose.JWK.createKeyStore()
const key = await a.generate('oct', 512)
console.log(key.toJSON(true))

Затем результат был сохранен в этом массиве:

const keystore = [
  {
    kty: 'oct',
    kid: 'QLdRkgyMx_po0fPo5XnOzQQB4iTcyay36m_PA62SBiw',
    k: 'A-OAikjssQZeLkj8N_2Xb9qPBG6lSq10YeLbiTF-kQuM_qKy08jwFqQwsLzn9fmNPkayM9uRg1lHBrPoK_fGtQ'
  }
]

Я пытался создать тот же JWE с тем же JWK в golang, и я могу расшифровать в golang, но ни в одном узле (у меня ошибка "ключ не найден")... Итак, перекрестное дешифрование не работает для меня. Что я делаю неправильно?

1 ответ

Решение

k представляет собой закодированное по base64url представление октетного ключа, если только интерфейс go специально не упоминает передачу ключей в JWK формат, которого нет, вам необходимо предоставить необработанный ключ. base64url.decode() в k чтобы получить необработанные ключевые байты.

Кроме того, в качестве примечания PBES2-HS256+A128KWпредназначен для использования с паролями, а не с ключами, учитывая его вычислительную сложность, я бы порекомендовал другой алгоритм упаковки ключей (не основанный на симметричной кодовой фразе). Вы можете использовать асимметричное шифрование для шифрования получателя. И если вы также хотите добиться аутентификации сообщения, вообще не используйте перенос ключей, вместо этого используйте прямое соглашение о ключах от JWE.

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