☰
Go JOSE v4 实战指南:基于 JWE / JWS / JWT 标准的 JSON 对象签名与加密实现
2026/9/25 2:44:46 网站建设 项目流程
  • 云原生

【免费下载链接】buildah

A tool that facilitates building OCI images.

项目地址:https://gitcode.com/gh_mirrors/bu/buildah
点击查看免费下载

导读

本文围绕 Buildah 仓库所 vendored 的go-josev4 文档,系统讲解 Go 语言中实现JSON Web Encryption(JWE)、JSON Web Signature(JWS)与JSON Web Token(JWT)三大 IETF 标准的核心库go-jose。你将掌握该库支持的算法与密钥类型全集、签名/加密的典型调用方式、多接收者模式的约束,以及它在容器签名与内容信任链路中的实际定位,从而能够在自己的 Go 项目中正确选型与使用 JOSE 消息格式。

一、库定位:Javascript Object Signing and Encryption(JOSE)标准族

go-jose的目标是在 Go 语言中完整实现Javascript Object Signing and Encryption系列标准,核心覆盖三大规范:

  • JSON Web Encryption(JWE)——RFC 7516,对 JSON 承载的数据进行加密;
  • JSON Web Signature(JWS)——RFC 7515,对 JSON 承载的数据进行数字签名与 MAC;
  • JSON Web Token(JWT)——RFC 7519,在 JWS / JWE 之上定义的令牌载体格式。

从 doc.go 的包级注释可以看到,库同时支持compact 序列化与JWS/JWE JSON 序列化两种消息格式,并可选支持多接收者(multiple recipients)模式。此外还附带一个小型命令行工具jose-util,可在 shell 中直接处理 JOSE 消息,便于调试与教学。

值得特别注意的是一个实现细节:go-jose 使用了一份从 Go 标准库 fork 出来的encoding/json实现(位于仓库内 json 子目录),它采用大小写敏感的成员名匹配,而非标准库的忽略大小写匹配。这样做的目的是避免 go-jose 与其他语言实现的库在解释消息字段时产生差异,从而保证跨语言互操作时的行为一致。

二、版本选择:v4 是当前稳定版本

该文档对版本策略有明确说明,这也是选型时首先要确认的事项:

  • Version 4(当前稳定版):import "github.com/go-jose/go-jose/v4",支持当前及前一个 Go release,当前要求Go 1.24;
  • Version 3:仅接收关键安全更新,官方建议迁移到 v4;
  • Version 1 与 2:已废弃,可在旧仓库square/go-jose中找到;
  • Version 5(预告):将引入若干破坏性 API 变更,并依赖 Go 标准库新的encoding/json/v2,该版本目前需要 Go 1.25 且以GOEXPERIMENT=jsonv2构建。

在 Buildah 仓库中,go-jose以v4.1.5的版本被 vendored:模块声明见 go.mod(github.com/go-jose/go-jose/v4 v4.1.5 // indirect),vendor 清单见 modules.txt,被 vendored 的包包括主包jose、jose/cipher与jose/json三个导入路径。也就是说,本文讲解的正是当前仓库实际落地使用的稳定版本。

三、支持的算法全集(RFC 7518 JSON Web Algorithms)

算法标识符与 RFC 7518 JSON Web Algorithms 标准中的名称保持一致。完整继承文档中的四张算法表如下。

3.1 密钥加密(Key Encryption)算法

密钥加密方式算法标识符
RSA-PKCS#1v1.5RSA1_5
RSA-OAEPRSA-OAEP, RSA-OAEP-256
AES 密钥包裹A128KW, A192KW, A256KW
AES-GCM 密钥包裹A128GCMKW, A192GCMKW, A256GCMKW
ECDH-ES + AES 密钥包裹ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW
ECDH-ES(直接)ECDH-ES1
直接加密dir1

1. ECDH-ES(直接)与 dir(直接加密)两种模式不支持多接收者模式。

3.2 签名 / MAC 算法

签名 / MAC 方式算法标识符
RSASSA-PKCS#1v1.5RS256, RS384, RS512
RSASSA-PSSPS256, PS384, PS512
HMACHS256, HS384, HS512
ECDSAES256, ES384, ES512
Ed25519EdDSA2

2. 文档在签名算法表中标注 EdDSA “仅在该库 version 2 中可用”,而在后文密钥类型表中则表述为“version 2 或之后”,结合本仓库 vendored 的 v4 代码(asymmetric.go 中实现 EdDSA 相关逻辑)可以确认:v4 版本实际支持 Ed25519/EdDSA。引用时请以你实际使用的版本为准。

3.3 内容加密(Content Encryption)算法

内容加密方式算法标识符
AES-CBC + HMACA128CBC-HS256, A192CBC-HS384, A256CBC-HS512
AES-GCMA128GCM, A192GCM, A256GCM

3.4 压缩算法

压缩方式算法标识符
DEFLATE(RFC 1951)DEF

从源码结构看,cipher 子目录中的 cbc_hmac.go(AES-CBC+HMAC 组合模式)、concat_kdf.go(ECDH-ES 的 Concat KDF 派生)、ecdh_es.go 与 key_wrap.go(AES 密钥包裹)正是上述算法表的底层实现载体,说明算法支持并非空头声明,而是有对应的密码学原语实现支撑。

四、支持的密钥类型

这些密钥类型被库所理解,可直接传给NewEncrypter或NewSigner等函数;每种密钥也都可以按需包装成JWK(JSON Web Key)以附加密钥 ID(kid)。

算法对应的 Go 类型
RSA*rsa.PublicKey,*rsa.PrivateKey
ECDH, ECDSA*ecdsa.PublicKey,*ecdsa.PrivateKey
EdDSA1ed25519.PublicKey,ed25519.PrivateKey
AES, HMAC[]byte

1. 文档注明 EdDSA 自该库 version 2 或之后可用。

JWK 的序列化/解析实现位于 jwk.go,它负责在标准 Go 密钥类型与 JWK 的 JSON 表示之间转换,并承载kid等元信息。

五、核心 API 与典型使用方式

该文档将代码示例指向 Godoc 参考与jose-util子目录,而本仓库 vendored 的源码则提供了最直接的函数签名证据,足以还原典型调用链。

5.1 签名与验签:NewSigner / NewMultiSigner / ParseSigned

签名入口定义在 signing.go:

func NewSigner(sig SigningKey, opts *SignerOptions) (Signer, error) func NewMultiSigner(sigs []SigningKey, opts *SignerOptions) (Signer, error)
  • NewSigner使用单个签名密钥构造Signer,可配合SignerOptions(如指定算法、附加kid等);
  • NewMultiSigner传入多个SigningKey,一次签名可产出多份签名的 JWS,是“多接收者”思想在签名侧的对偶实现。

验签入口定义在 jws.go:

func ParseSigned(input string) (*JSONWebSignature, error) func ParseSignedCompact(input string, algs []SignatureAlgorithm) (*JSONWebSignature, error) func ParseSignedJSON(input string, algs []SignatureAlgorithm) (*JSONWebSignature, error)

典型流程:NewSigner构造签名器 → 对 payload 调用Sign生成 JWS 字符串 → 对方用ParseSigned(或ParseSignedCompact)解析 → 通过DetachedVerify/Verify校验签名。

5.2 加密与解密:NewEncrypter / NewMultiEncrypter / ParseEncrypted

加密入口定义在 crypter.go:

func NewEncrypter(enc ContentEncryption, rcpt Recipient, opts *EncrypterOptions) (Encrypter, error) func NewMultiEncrypter(enc ContentEncryption, rcpts []Recipient, opts *EncrypterOptions) (Encrypter, error)
  • 第一个参数enc指定内容加密算法(如A256GCM、A128CBC-HS256);
  • 第二个参数rcpt/rcpts指定接收者,即密钥加密算法与密钥(如RSA-OAEP+ RSA 公钥);
  • NewMultiEncrypter支持多个接收者:同一密文可分别用不同密钥加密(对应文档所述的多接收者模式)。

解密入口定义在 jwe.go:

func ParseEncrypted(input string, keyIDAlg string) (*JSONWebEncryption, error) func ParseEncryptedJSON(input string, keyIDAlg string) (*JSONWebEncryption, error) func ParseEncryptedCompact(input string, keyIDAlg string) (*JSONWebEncryption, error)

典型流程:NewEncrypter构造加密器 →Encrypt生成 JWE → 对方用ParseEncrypted解析后调用Decrypt还原明文。需要重申的是:ECDH-ES(直接)与dir两种密钥加密算法不支持多接收者模式,在NewMultiEncrypter场景中应选用支持多接收者的算法。

5.3 序列化格式小结

综合 jws.go 与 jwe.go 的解析函数族可以归纳出三种入口形态:

  • Compact 形态:ParseSignedCompact/ParseEncryptedCompact,即base64url(header).base64url(payload).signature这种紧凑字符串,最常用于 HTTP 头(Authorization: Bearer ...)等单行场景;
  • JSON 形态:ParseSignedJSON/ParseEncryptedJSON,对应 JWS/JWE 的 JSON 序列化,便于承载多签名、多接收者等复杂结构;
  • 通用形态:ParseSigned/ParseEncrypted自动分派到上述两种格式。

六、在 Buildah 仓库中的角色:容器签名信任链的间接依赖

go-jose并非 Buildah 直接调用的库,而是以indirect(间接)依赖的形式出现在 go.mod 中。从依赖拓扑推断,它经由sigstore系的签名工具链(go.sum 中github.com/sigstore/fulcio、github.com/sigstore/sigstore等组件)传递引入,服务于镜像签名生成与验证、签名材料(如cosign风格的签名负载)等与内容信任相关的场景——这与 Buildah 作为 OCI 镜像构建工具在buildah push/buildah commit等流程中涉及签名与校验的能力相吻合。对于使用者而言,这意味着:

  • 在使用 Buildah 源码时无需直接 importgo-jose,其 API 通过间接依赖被自动带入(vendor 模式下由 vendor/modules.txt 锁定);
  • 若你独立开发涉及 JOSE/JWT 的 Go 服务,则可直接go get github.com/go-jose/go-jose/v4,并使用上文列出的NewSigner/NewEncrypter/ParseSigned/ParseEncrypted等 API。

七、使用注意事项与迁移建议

  1. 区分“签名算法”与“内容加密算法”:JWS 只解决完整性与真实性(签名/MAC),JWE 才解决机密性(加密),JWT 则可基于两者之一承载声明。选型时先明确需求是防篡改还是防泄露。
  2. 多接收者模式的算法限制:ECDH-ES(直接)与dir不可用于多接收者;多接收者加密时优先选择 RSA-OAEP、AES-KW、AES-GCMKW 或 ECDH-ES+KW 族。
  3. 大小写敏感 JSON 解析:由于 go-jose fork 的 json 实现按成员名大小写敏感匹配,消息字段命名必须严格符合标准拼写(如alg、typ、kid),跨语言互操作时尤其要注意。
  4. 版本迁移:v3 仅接收关键安全更新,v1/v2 已废弃,新项目应直接使用 v4;关注未来 v5 的破坏性 API 变更(其依赖 Go 1.25 +GOEXPERIMENT=jsonv2构建的encoding/json/v2),迁移前先评估工具链兼容性。
  5. 安全实践:优先选择 AEAD 类内容加密算法(如 AES-GCM)并配合现代密钥加密算法(如 RSA-OAEP-256);RSA1_5属于历史兼容算法,在满足互操作要求的前提下应谨慎使用。

结语

go-jose是 Go 生态中实现 JOSE 标准族的主流选择:它以 RFC 7515/7516/7519/7518 为规范依据,覆盖完整的密钥加密、签名/MAC、内容加密与压缩算法矩阵,同时支持 compact 与 JSON 两种序列化形态。本文依据 README.md 的算法与密钥表格,结合仓库内 signing.go、crypter.go、jws.go、jwe.go 等源码还原了其 API 入口与使用要点。对于 Buildah 的开发者,理解这份依赖有助于深入排查镜像签名与内容信任链路;对于独立 Go 开发者,上述 API 与表格可直接用于 JWE/JWS/JWT 的落地实现。

  • 云原生

【免费下载链接】buildah

A tool that facilitates building OCI images.

项目地址:https://gitcode.com/gh_mirrors/bu/buildah
点击查看免费下载
上一篇:NeteaseMusic开发者指南:API集成与双平台资源融合实现
下一篇:Checkov内存泄漏排查:大规模扫描稳定性保障

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询