在 golang 中解密 JWE 令牌
Decrypting JWE token in golang
我有这个问题,我用node-jose在node.js中创建了一个JWE,方法是这样的:
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'
}
]
我一直在尝试在 golang 中使用相同的 JWK 创建相同的 JWE,我可以在 golang 中解密,但在 node 中都不能(我得到了 "key not found" 错误)...所以,交叉解密不会为我工作。我做错了什么?
k
是八位位组密钥的 base64url 编码表示,除非 go 接口特别提到以 JWK
格式传递密钥,但它没有,否则您需要提供原始密钥。 base64url.decode()
k
获取原始密钥字节。
此外,作为旁注,PBES2-HS256+A128KW
旨在与密码一起使用,而不是密钥,鉴于它的计算量很大,我建议使用不同的密钥包装算法(不是基于对称密码的算法)。您可以使用非对称加密为收件人加密。如果您还想实现消息的身份验证,则根本不要使用密钥包装,而是使用 JWE 中的直接密钥协议。
我有这个问题,我用node-jose在node.js中创建了一个JWE,方法是这样的:
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'
}
]
我一直在尝试在 golang 中使用相同的 JWK 创建相同的 JWE,我可以在 golang 中解密,但在 node 中都不能(我得到了 "key not found" 错误)...所以,交叉解密不会为我工作。我做错了什么?
k
是八位位组密钥的 base64url 编码表示,除非 go 接口特别提到以 JWK
格式传递密钥,但它没有,否则您需要提供原始密钥。 base64url.decode()
k
获取原始密钥字节。
此外,作为旁注,PBES2-HS256+A128KW
旨在与密码一起使用,而不是密钥,鉴于它的计算量很大,我建议使用不同的密钥包装算法(不是基于对称密码的算法)。您可以使用非对称加密为收件人加密。如果您还想实现消息的身份验证,则根本不要使用密钥包装,而是使用 JWE 中的直接密钥协议。