如何在Golang中验证NextAuth生成的A256GCM算法JWE令牌
问题解决:Go-jose解密NextAuth生成的A256GCM JWE令牌报错
错误原因
你遇到的panic: square/go-jose: error in cryptographic primitive错误,核心原因是密钥长度不符合A256GCM算法要求:
- A256GCM算法需要32字节(256位)的对称密钥,但你使用的密钥字符串
thisisaverylongtextusedforhashing转成UTF-8字节后长度为33,不满足算法的密钥长度要求。 - 另外,NextAuth生成JWE时可能会对输入密钥做规范化处理(如截断、派生),如果Go端未同步该处理逻辑,也会导致密钥不匹配。
解决方案
方案一:调整密钥为32字节长度
直接将密钥修改为刚好32字符的字符串,确保两端(NextAuth和Go服务)使用完全一致的密钥:
rawToken := `eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..aiIqD7-cU8Hu92F8.Kx2k99cyLYJR1P0xK_1wUsVO521T7kYSKx-OEutVJcpzbX27hZH0kh2MlBLxQHdmc8q4uXglhjl4JE3nTp_c6nOjga-faHyxYqKrZGJFLlu9MC4JVUWyonX6doFq0gl3UX9ABtP2t35Qly-w1qKH8BdG9x4iB1YM-yvs1w-HpBbMFQR7U7X4oHWIh_YJQlWADesYq6da7A97GSSXs2Go6yb7SH5WWd7iQzDu-UO6eg._PqujCUyMUqOkID80vJiDw` // 调整为32字符的密钥 key := []byte("thisisaverylongtextusedforhashin") 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)
方案二:模拟NextAuth的密钥派生逻辑
如果必须保留原密钥字符串,需要在Go端按照NextAuth的密钥派生规则生成符合要求的32字节密钥。NextAuth通常使用HKDF-SHA-256算法派生密钥,示例代码:
import ( "crypto/sha256" "fmt" "io" "github.com/golang-jwt/jwt/v4" "golang.org/x/crypto/hkdf" ) func deriveKey(rawKey []byte) ([]byte, error) { // 模拟NextAuth的HKDF派生逻辑,盐设为nil,信息字段标识JWE用途 hkdf := hkdf.New(sha256.New, rawKey, nil, []byte("NextAuth JWE")) key := make([]byte, 32) _, err := io.ReadFull(hkdf, key) return key, err } func main() { rawToken := `eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..aiIqD7-cU8Hu92F8.Kx2k99cyLYJR1P0xK_1wUsVO521T7kYSKx-OEutVJcpzbX27hZH0kh2MlBLxQHdmc8q4uXglhjl4JE3nTp_c6nOjga-faHyxYqKrZGJFLlu9MC4JVUWyonX6doFq0gl3UX9ABtP2t35Qly-w1qKH8BdG9x4iB1YM-yvs1w-HpBbMFQR7U7X4oHWIh_YJQlWADesYq6da7A97GSSXs2Go6yb7SH5WWd7iQzDu-UO6eg._PqujCUyMUqOkID80vJiDw` rawKey := []byte("thisisaverylongtextusedforhashing") // 派生32字节密钥 key, err := deriveKey(rawKey) if err != nil { panic(err) } 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) }
方案三:确认NextAuth配置一致性
确保NextAuth的JWT加密配置使用的密钥和Go端完全一致,避免额外的密钥处理:
// NextAuth配置示例 export default NextAuth({ session: { strategy: "jwt" }, jwt: { encryption: true, secret: "thisisaverylongtextusedforhashing", // 与Go端密钥一致 }, // 其他配置项 })
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

