跳到主要内容
ecdsa.com
go-jose (Go)Go

错误信息

go-jose/go-jose: error in cryptographic primitive

也可能输出为

  • square/go-jose: error in cryptographic primitive

go-jose v2(以 gopkg.in/square/go-jose.v2 导入)使用前缀“square/go-jose:”;v3 和 v4 使用“go-jose/go-jose:”。JWE 解密失败时返回的也是同一个错误。

go-jose (Go) — jose.ErrCryptoFailure from JSONWebSignature.Verify / jwt.JSONWebToken.Claims

含义

这是 go-jose 通用的签名(或解密)失败错误 `jose.ErrCryptoFailure`。JWS 已成功解析,算法也在允许范围内,但用你传入的密钥验证签名失败了。go-jose 有意不提供更多信息——在验证者看来,密钥错误和令牌被篡改是一样的——因此排查总是围绕两个问题:你传入的是哪个密钥?令牌有没有被改动?

原因

修复方法

  1. 1.

    按 kid 选择密钥,再校验声明

    根据头部的 `kid` 从颁发者的 JWKS 中确定唯一一个密钥,验证签名,然后用 `Claims.Validate` 校验 `iss`、`aud` 和 `exp`——go-jose 不会自行检查声明。

    go
    // keys: *jose.JSONWebKeySet fetched from the issuer's jwks_uri
    parsed, err := jwt.ParseSigned(raw, []jose.SignatureAlgorithm{jose.ES256})
    if err != nil {
    	return err
    }
    kid := parsed.Headers[0].KeyID
    matches := keys.Key(kid) // all keys with this kid
    if len(matches) != 1 {
    	return fmt.Errorf("no unique key for kid %q", kid)
    }
    var claims jwt.Claims
    if err := parsed.Claims(matches[0].Key, &claims); err != nil {
    	return err
    }
    return claims.Validate(jwt.Expected{Issuer: "https://issuer.example.com/", AnyAudience: jwt.Audience{"api"}, Time: time.Now()})

相关错误

浏览完整的签名错误库