- 云原生
【免费下载链接】buildah
A tool that facilitates building OCI images.
导读
本文围绕 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.5 | RSA1_5 |
| RSA-OAEP | RSA-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.5 | RS256, RS384, RS512 |
| RSASSA-PSS | PS256, PS384, PS512 |
| HMAC | HS256, HS384, HS512 |
| ECDSA | ES256, ES384, ES512 |
| Ed25519 | EdDSA2 |
2. 文档在签名算法表中标注 EdDSA “仅在该库 version 2 中可用”,而在后文密钥类型表中则表述为“version 2 或之后”,结合本仓库 vendored 的 v4 代码(asymmetric.go 中实现 EdDSA 相关逻辑)可以确认:v4 版本实际支持 Ed25519/EdDSA。引用时请以你实际使用的版本为准。
3.3 内容加密(Content Encryption)算法
| 内容加密方式 | 算法标识符 |
|---|---|
| AES-CBC + HMAC | A128CBC-HS256, A192CBC-HS384, A256CBC-HS512 |
| AES-GCM | A128GCM, 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 |
| EdDSA1 | ed25519.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 源码时无需直接 import
go-jose,其 API 通过间接依赖被自动带入(vendor 模式下由 vendor/modules.txt 锁定); - 若你独立开发涉及 JOSE/JWT 的 Go 服务,则可直接
go get github.com/go-jose/go-jose/v4,并使用上文列出的NewSigner/NewEncrypter/ParseSigned/ParseEncrypted等 API。
七、使用注意事项与迁移建议
- 区分“签名算法”与“内容加密算法”:JWS 只解决完整性与真实性(签名/MAC),JWE 才解决机密性(加密),JWT 则可基于两者之一承载声明。选型时先明确需求是防篡改还是防泄露。
- 多接收者模式的算法限制:
ECDH-ES(直接)与dir不可用于多接收者;多接收者加密时优先选择 RSA-OAEP、AES-KW、AES-GCMKW 或 ECDH-ES+KW 族。 - 大小写敏感 JSON 解析:由于 go-jose fork 的 json 实现按成员名大小写敏感匹配,消息字段命名必须严格符合标准拼写(如
alg、typ、kid),跨语言互操作时尤其要注意。 - 版本迁移:v3 仅接收关键安全更新,v1/v2 已废弃,新项目应直接使用 v4;关注未来 v5 的破坏性 API 变更(其依赖 Go 1.25 +
GOEXPERIMENT=jsonv2构建的encoding/json/v2),迁移前先评估工具链兼容性。 - 安全实践:优先选择 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.
相关推荐
go-jose v4 完整指南:在 Go 中实现 JWE / JWS / JWT 的标准级加密与签名
go jose v4 完整指南:在 Go 中实现 JWE / JWS / JWT 的标准级加密与签名 本指南以当前仓库中 vendor 化的 go jose v
人工智能AI AgentAgent 沙箱云原生容器运行时零信任go-jose v4 完全指南:用 Go 实现 JWE/JWS/JWT 签名与加密
go jose v4 完全指南:用 Go 实现 JWE/JWS/JWT 签名与加密 导读 go jose (Go JOSE)是 Go 生态中最常用的 JSON
容器运行时云原生CLIgo-jose v4 完全指南:在 Go 中实现 JWE 加密、JWS 签名与 JWT 的实战解析
go jose v4 完全指南:在 Go 中实现 JWE 加密、JWS 签名与 JWT 的实战解析 go jose 是 Go 语言对 JavaScript Ob
网络安全
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考