sigstore/timestamp-authority

GitHub: sigstore/timestamp-authority

Sigstore Timestamp Authority 提供符合 RFC 3161 标准的签名时间戳服务,用于在软件签名和验证流程中建立可独立验证的时间证据。

Stars: 136 | Forks: 63

[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/sigstore/timestamp-authority/badge)](https://api.securityscorecards.dev/projects/github.com/sigstore/timestamp-authority) # Sigstore Timestamp Authority 一个用于签发 [RFC 3161 时间戳](https://datatracker.ietf.org/doc/html/rfc3161)的服务。 时间戳符合 [RFC 3628 策略](https://datatracker.ietf.org/doc/html/rfc3628)。 时间戳结构符合 [RFC 5816](https://datatracker.ietf.org/doc/rfc5816) 中的更新。 ## 安全模型 [可信时间戳](https://en.wikipedia.org/wiki/Trusted_timestamping) 是一个存在已久的过程。 它提供了文档何时创建或修改的时间戳记录。 时间戳授权机构使用公钥基础设施创建签名的时间戳。时间戳授权机构的操作员必须保护签名密钥材料,以防止未经授权的时间戳签名。 时间戳授权机构还应验证自己的时钟。我们提供了一个配置,可以定期与知名的 NTP 源核对当前时间。 ## Sigstore 中的时间戳 时间戳是 [Rekor](https://github.com/sigstore/rekor)(Sigstore 的签名透明度日志)的关键组件。 时间戳用于验证短期证书。目前,时间戳来自 Rekor 自身的内部时钟,这在外部是无法验证且不可变的。使用由时间戳授权机构签发的签名时间戳,可以减轻 Rekor 时钟被篡改的风险。 作为构件签名者,你可以: * 对构件生成签名 * 获取该签名的时间戳(更多内容见下文[对什么进行签名](#what-to-sign)) * 将签名、构件哈希和证书上传到 Rekor(hashedrekord 记录类型) * 将时间戳上传到 Rekor(rfc3161 记录类型) * 此步骤非常重要,因为它使时间戳可以接受公开审计 作为构件验证者: * 从 Rekor 获取构件条目 * 如果构件是使用证书签名的,验证其是否过期 * 如果你信任 Rekor 的时钟,请使用 Rekor 响应中的时间戳验证证书 * 如果你信任外部时间戳授权机构,请从 Rekor 获取时间戳,验证签名的时间戳,并使用签名的时间戳验证证书 ### 对什么进行签名 在 Sigstore 中使用时,我们建议对与签名相关联的值进行签名。 对于 [Cosign](https://github.com/sigstore/cosign/),我们选择对构件签名进行签名,这个过程称为“副签 (countersigning)”。我们直接对原始签名字节进行签名,而不是 base64 编码的值。对签名进行签名可以确保是签名(而非构件)在特定时间创建的。 ## 本地开发 前置条件:在 macOS 上,我们目前需要安装 `openssl`。 ``` brew install openssl ``` 要启动服务器,请运行以下任一命令: * `docker-compose up` * `make timestamp-server && ./bin/timestamp-server serve --port 3000` 这两个命令都会使用内存中的签名密钥和证书链启动服务器。**这不应用于生产环境。** 要使用提供的 `timestamp-cli` 获取时间戳: 1. 获取验证链:`curl http://localhost:3000/api/v1/timestamp/certchain > ts_chain.pem` 2. 创建要签名的测试数据包:`echo "myblob" > myblob` 3. 构建客户端:`make timestamp-cli` 4. 获取时间戳:`./bin/timestamp-cli --timestamp_server http://localhost:3000 timestamp --hash sha256 --artifact myblob --out response.tsr` 5. 验证时间戳:`./bin/timestamp-cli verify --timestamp response.tsr --artifact "myblob" --certificate-chain ts_chain.pem --format json` 6. 检查时间戳:`./bin/timestamp-cli inspect --timestamp response.tsr --format json` 要使用 `openssl` 和 `curl` 获取时间戳: 1. 获取验证链:`curl http://localhost:3000/api/v1/timestamp/certchain > ts_chain.pem` 2. 将证书链拆分为根 CA 证书和“不受信任的”中间及叶子证书: 1. 拆分:`csplit -s -f tmpcert- ts_chain.pem '/-----BEGIN CERTIFICATE-----/' '{*}'` * 注意,在 macOS 上,你需要使用 `brew install coreutils` 安装 GNU 实用程序,并使用 `gcsplit` 2. 删除空文件:`rm tmpcert-00` 3. 获取根证书:`mv $(ls tmpcert-* | tail -1) root.crt.pem` 4. 合并剩余证书:`cat tmpcert-* > chain.crts.pem` 5. 删除临时文件:`rm tmpcert-*` 3. 创建要签名的测试数据包:`echo "myblob" > myblob` 4. 创建时间戳请求:`openssl ts -query -data myblob -cert -sha256 -out request.tsq` 5. 获取时间戳:`curl -sSH "Content-Type: application/timestamp-query" --data-binary @request.tsq http://localhost:3000/api/v1/timestamp -o response.tsr` 6. 验证时间戳:`openssl ts -verify -in response.tsr -data "myblob" -CAfile root.crt.pem -untrusted chain.crts.pem` * 请注意,你会看到一个警告,提示某个证书“不是 CA 证书”,但这是预期的,因为你需要提供 TSA 签名证书,以防响应中未包含该证书。生成时间戳查询时,设置 `-cert` 将强制要求包含签名证书。 7. 检查时间戳:`openssl ts -reply -in response.tsr -text` ### 使用 JSON 发出请求 如果你想使用基于 JSON 的请求来请求时间戳,可以这样做: `curl -sSH "Content-Type: application/json" -d @request.json http://localhost:3000/api/v1/timestamp -o response.tsr` 服务期望的 JSON 主体格式为: ``` { "artifactHash": "", "certificates": true, "hashAlgorithm": "sha256", "nonce": 1123343434, "tsaPolicyOID": "1.2.3.4" } ``` 构件哈希必须表示为 base64 编码的字符串。 ## 生产环境部署 要部署到生产环境,时间戳授权机构目前支持使用 Cloud KMS 或 [Tink](https://github.com/tink-crypto) 进行签名。你需要提供一个证书链(叶子证书、任何中间证书和根证书),并且该证书链的用途(扩展密钥用法)须用于时间戳。我们不推荐将文件签名器用于生产环境,因为签名密钥仅受密码保护。 #### 中间证书 请注意,默认情况下,`timestamp-server` 会强制要求叶子证书*以及*任何中间证书具有时间戳的扩展密钥用法 (EKU) 并设置为关键 (critical)。如果你想对中间证书禁用此强制要求,请设置 `--enforce-intermediate-eku=false`。 ### Certificate Maker Certificate Maker 是一个用于为 Timestamp Authority 创建符合 RFC 3161 标准证书链的工具。它支持: * 两级证书链: * root → leaf * root → intermediate * 三级证书链: * root → intermediate → leaf * 多种 KMS 提供商(AWS、Google Cloud、Azure、HashiCorp Vault) 有关详细的使用说明和示例,请参阅 [Certificate Maker 文档](docs/certificate-maker.md)。 ### Cloud KMS 生成一个证书链,该链必须包含一个公钥与 Cloud KMS 中私钥配对的叶子证书,可包含任意数量的中间证书,并且必须包含一个根证书。 如果你不想使用 GCP,我们建议查看用于生成证书链的[代码](https://github.com/sigstore/timestamp-authority/blob/main/cmd/fetch-tsa-certs/fetch_tsa_certs.go)。 #### 示例:GCP 上的时间戳签名密钥,GCP 上的中间密钥,GCP 上的根 CA * 使用 [GCP CA Service](https://cloud.google.com/certificate-authority-service) 创建一个根 CA。配置生命周期,其他默认设置可以保持不变。你需要先创建一个 CA 池,然后在该池中创建一个 CA。 * 在 KMS 上创建一个非对称证书签名密钥,它将用作签署 TSA 证书的中间 CA。 * 在 KMS 上创建一个非对称时间戳签名密钥。 * 运行以下命令以创建包含根证书、中间证书和叶子证书的证书链 go run cmd/fetch-tsa-certs/fetch_tsa_certs.go \ --leaf-kms-resource="gcpkms://projects//locations//keyRings//cryptoKeys//versions/1" \ --parent-kms-resource="gcpkms://projects//locations//keyRings//cryptoKeys//versions/1" \ --gcp-ca-parent="projects//locations//caPools/" \ --org-name="example.com" --output="chain.crt.pem" #### 示例:GCP 上的签名密钥,GCP 上的自签名根证书 * 在 KMS 上创建一个非对称证书签名密钥,它将用于自签名证书以签署 TSA 证书。 * 在 KMS 上创建一个非对称时间戳签名密钥。 * 运行以下命令以创建由自签名证书和叶子签名证书组成的链: go run cmd/fetch-tsa-certs/fetch_tsa_certs.go \ --leaf-kms-resource="gcpkms://projects//locations//keyRings//cryptoKeys//versions/1" \ --parent-kms-resource="gcpkms://projects//locations//keyRings//cryptoKeys//versions/1" \ --parent-validity= --org-name="example.com" --output="chain.crt.pem" #### 示例:AWS 上的密钥 有关使用基于 AWS KMS 的密钥和 Certificate Maker 运行服务器的一般流程,请参阅[这些说明](docs/aws-kms.md)。 #### 其他 KMS 如果你没有使用 GCP,有很多可能的选项,但设置证书的步骤可能类似于以下内容: * 创建一个 KMS 私钥(例如,在 AWS KMS 中) * 使用此私钥创建一个 CSR * 假设你有一个外部的(例如,企业等)证书授权机构实体可以签署该 CSR,让它签署生成的 CSR 并生成证书。确保叶子证书——即用于签署时间戳请求的证书——设置了时间戳 EKU (Extended Key Usage) 并标记为 Critical。 * 如有必要,将 CA、中间证书和叶子证书合并到证书链文件中。使用 [VerifyCertChain](https://github.com/sigstore/timestamp-authority/blob/main/pkg/x509/x509.go#L35) 验证证书链格式,以确保它与 `timestamp_server` 预期的格式兼容。 设置 `--timestamp-signer=kms`,使用 `--certificate-chain-path` 提供证书链路径,并使用 `--kms-key-resource` 提供 KMS 密钥。密钥的前缀必须是 `gcpkms://`、`azurekms://`、`awskms://` 或 `hashivault://`。 ### Tink [Tink](https://github.com/google/tink) 是一个易于使用的跨语言加密库。 时间戳授权机构提供了一个使用 Tink 的签名器,它支持通过安全的磁盘密钥存储进行内存签名。密钥不是受密码保护,而是使用 Cloud KMS 密钥进行加密,并在启动时解密。 首先安装 [tinkey](https://github.com/google/tink/blob/master/docs/TINKEY.md)。 #### 示例:Tinkey 作为时间戳签名密钥,GCP 上的中间密钥,GCP 上的根 CA * 在 GCP 中创建一个对称密钥加密密钥 * 运行以下命令创建本地加密的签名密钥,如有需要可更改密钥 URI 和密钥模板: tinkey create-keyset --key-template ECDSA_P384 --out enc-keyset.cfg --master-key-uri gcp-kms://projects//locations//keyRings//cryptoKeys/ * 使用 [GCP CA Service](https://cloud.google.com/certificate-authority-service) 创建一个根 CA。配置生命周期,其他默认设置可以保持不变。你需要先创建一个 CA 池,然后在该池中创建一个 CA。 * 在 KMS 上创建一个非对称签名密钥,它将用作签署 TSA 证书的中间 CA。 * 运行以下命令: go run cmd/fetch-tsa-certs/fetch_tsa_certs.go \ --tink-kms-resource="gcp-kms://projects//locations//keyRings//cryptoKeys/"\ --tink-keyset-path="enc-keyset.cfg"\ --parent-kms-resource="gcpkms://projects//locations//keyRings//cryptoKeys//versions/1"\ --gcp-ca-parent="projects//locations//caPools/"\ --org-name="example.com" --output="chain.crt.pem" #### 示例:Tinkey 作为时间戳签名密钥,GCP 上的自签名根证书 * 在 GCP 中创建一个对称密钥加密密钥 * 运行以下命令创建本地加密的签名密钥,如有需要可更改密钥 URI 和密钥模板: tinkey create-keyset --key-template ECDSA_P384 --out enc-keyset.cfg --master-key-uri gcp-kms://projects//locations//keyRings//crypto/ * 在 KMS 上创建一个非对称签名密钥,它将用于自签名证书以签署 TSA 证书。 * 运行以下命令: go run cmd/fetch-tsa-certs/fetch_tsa_certs.go \ --tink-kms-resource="gcp-kms://projects//locations//keyRings//cryptoKeys/"\ --tink-keyset-path="enc-keyset.cfg"\ --parent-kms-resource="gcpkms://projects//locations//keyRings//cryptoKeys//versions/1"\ --parent-validity= --org-name="example.com" --output="chain.crt.pem" #### 使用 tinkey 运行 Timestamp Authority 要运行 TSA,请设置 `--timestamp-signer=tink`、`--tink-key-resource=` 和 `--tink-keyset-path=enc-keyset.cfg`。密钥资源的前缀必须是 `gcp-kms://`、`aws-kms://` 或 `hcvault://`。 如果使用 Vault,你还可以设置 `--tink-hcvault-token`。使用 `--certificate-chain-path` 提供证书链的路径。 ## 时间准确性与监控 可以将服务配置为监控来自其他可信 NTP 源的时间,并与主机的时间进行比较。如果响应的 NTP 服务器过少,或者时间差大于当前配置的阈值,则 `timestamp_authority_ntp_errors_total` 指标将会增加。请注意,该服务_并不会停止签发时间戳_。运营商有责任配置必要的控制措施,以防止在时间偏差大于时间戳策略中所述的值时签发时间戳。 ## 安全 如果您发现任何安全问题,请参阅 Sigstore 的[安全流程](https://github.com/sigstore/.github/blob/main/SECURITY.md)。
标签:EVTX分析, 安全测试工具, 日志审计, 请求拦截