4.2. 轮转证书转换日志签名者密钥


您可以使用分片功能冻结日志树,主动轮转证书转换(CT)日志签名程序密钥,并使用新的签名程序密钥创建新日志树。此流程指导您完成旧的 CT 日志签名程序密钥,并使用 Red Hat Trusted Artifact Signer (RHTAS)的新 signer 密钥替换它。使旧的 CT 日志签名器密钥过期仍允许您验证旧密钥签名的工件。

先决条件

  • 安装在 Red Hat OpenShift Container Platform 上运行的 RHTAS operator。
  • 正在运行的 Securesign 实例。
  • 安装了 ocopensslcosign 二进制文件的工作站。

流程

  1. tuftool 二进制文件从 OpenShift 集群下载到您的工作站。

    重要

    tuftool 二进制文件仅适用于 Linux 操作系统。

    1. 在主页中,单击 ? 图标,单击 Command line tools,转至 tuftool 下载部分,然后点击您的平台的链接。
    2. 在工作站上打开一个终端,解压缩二进制 .gz 文件,并设置 execute 位:

      Example

      $ gunzip tuftool-amd64.gz
      $ chmod +x tuftool-amd64
      Copy to clipboard

    3. 将二进制文件移到 $PATH 环境中的位置:

      Example

      $ sudo mv tuftool-amd64 /usr/local/bin/tuftool
      Copy to clipboard

  2. 从命令行登录到 OpenShift:

    语法

    oc login --token=TOKEN --server=SERVER_URL_AND_PORT
    Copy to clipboard

    Example

    $ oc login --token=sha256~ZvFDBvoIYAbVECixS4-WmkN4RfnNd8Neh3y1WuiFPXC --server=https://example.com:6443
    Copy to clipboard

    注意

    您可以从 OpenShift Web 控制台找到用于命令行的登录令牌和 URL。登录 OpenShift Web 控制台。单击您的用户名,然后单击 Copy login command。如果被要求,再次提供您的用户名和密码,然后单击 Display Token 以查看该命令。

  3. 切换到 RHTAS 项目:

    Example

    $ oc project trusted-artifact-signer
    Copy to clipboard

  4. 备份当前的 CT 日志配置和密钥:

    Example

    $ export SERVER_CONFIG_NAME=$(oc get ctlog -o jsonpath='{.items[0].status.serverConfigRef.name}')
    $ oc get secret $SERVER_CONFIG_NAME -o jsonpath="{.data.config}" | base64 --decode > config.txtpb
    $ oc get secret $SERVER_CONFIG_NAME -o jsonpath="{.data.fulcio-0}" | base64 --decode > fulcio-0.pem
    $ oc get secret $SERVER_CONFIG_NAME -o jsonpath="{.data.private}" | base64 --decode > private.pem
    $ oc get secret $SERVER_CONFIG_NAME -o jsonpath="{.data.public}" | base64 --decode > public.pem
    Copy to clipboard

  5. 捕获当前树标识符:

    Example

    $ export OLD_TREE_ID=$(oc get ctlog -o jsonpath='{.items[0].status.treeID}')
    Copy to clipboard

  6. 将日志树设置为 DRAINING 状态:

    Example

    $ oc run --image registry.redhat.io/rhtas/updatetree-rhel9:1.1.0 --restart=Never --attach=true --rm=true -q -- updatetree --admin_server=trillian-logserver:8091 --tree_id=${OLD_TREE_ID} --tree_state=DRAINING
    Copy to clipboard

    在排空时,树形日志不接受任何新条目。观察并等待队列为空。

    重要

    您必须等待队列为空,然后继续下一步。如果在排空时保留仍然集成,则在此过程中冻结日志树可能会导致日志路径超过最大合并延迟(MMD)。

  7. 队列完全排空后,冻结日志:

    Example

    $ oc run --image registry.redhat.io/rhtas/updatetree-rhel9:1.1.0 --restart=Never --attach=true --rm=true -q -- updatetree --admin_server=trillian-logserver:8091 --tree_id=${OLD_TREE_ID} --tree_state=FROZEN
    Copy to clipboard

  8. 创建新的 Merkle 树,并捕获新的树标识符:

    Example

    $ export NEW_TREE_ID=$(kubectl run createtree --image registry.redhat.io/rhtas/createtree-rhel9:1.1.0 --restart=Never --attach=true --rm=true -q -- -logtostderr=false --admin_server=trillian-logserver:8091 --display_name=ctlog-tree)
    Copy to clipboard

  9. 生成新证书,以及新的公钥和私钥:

    Example

    $ openssl ecparam -genkey -name prime256v1 -noout -out new-ctlog.pem
    $ openssl ec -in new-ctlog.pem -pubout -out new-ctlog-public.pem
    $ openssl ec -in new-ctlog.pem -out new-ctlog.pass.pem -des3 -passout pass:"CHANGE_ME"
    Copy to clipboard

    CHANGE_ME 替换为新密码。

    重要

    证书和密钥必须具有唯一的文件名。

  10. 更新 CT 日志配置。

    1. 打开 config.txtpb 文件进行编辑。
    2. 对于 frozen 日志,将 not_after_limit 字段添加到 frozen 日志条目中,将前缀值重命名为唯一名称,并使用 ctfe-keys/private-0 替换到私钥的旧路径:

      Example

      ...
      log_configs:{
        # frozen log
        config:{
          log_id:2066075212146181968
          prefix:"trusted-artifact-signer-0"
          roots_pem_file:"/ctfe-keys/fulcio-0"
          private_key:{[type.googleapis.com/keyspb.PEMKeyFile]:{path:"/ctfe-keys/private-0" password:"Example123"}}
          public_key:{der:"0Y0\x13\x06\x07*\x86H\xce=\x02\x01\x06\x08*\x86H\xce=\x03\x01\x07\x03B\x00\x04)'.\xffUJ\xe2s)\xefR\x8a\xfcO\xdcewȶy\xa7\x9d<\x13\xb0\x1c\x99\x96\xe4'\xe3v\x07:\xc8I+\x08J\x9d\x8a\xed\x06\xe4\xaeI:q\x98\xf4\xbc<o4VD\x0cr\xf9\x9c\xecxT\x84"}
          not_after_limit:{seconds:1728056285 nanos:012111000}
          ext_key_usages:"CodeSigning"
          log_backend_name:"trillian"
        }
      Copy to clipboard

      注意

      您可以运行以下命令来获取秒和纳秒的当前时间值: date +%s,以及 date +%N

      重要

      not_after_limit 字段仅定义 frozen 日志的时间戳范围的末尾。除此刻外的证书不再接受在此日志中包括的证书。

    3. 复制并粘贴 frozen 日志 配置 块,将其附加到配置文件中以创建新条目。
    4. 更改新 config 块中的以下行:将 log_id 设置为新的树标识符,将 前缀 改为 trusted-artifact-signer,将 private_key 路径更改为 ctfe-keys/private,删除 public_key 行,并将 not_after_limit 更改为 not_after_start 并设置时间戳范围:

      Example

      ...
      log_configs:{
        # frozen log
        ...
        # new active log
        config:{
      	  log_id: NEW_TREE_ID
      	  prefix:"trusted-artifact-signer"
      	  roots_pem_file:"/ctfe-keys/fulcio-0"
      	  private_key:{[type.googleapis.com/keyspb.PEMKeyFile]:{path:"ctfe-keys/private" password:"CHANGE_ME"}}
      	  ext_key_usages:"CodeSigning"
      	  not_after_start:{seconds:1713201754 nanos:155663000}
      	  log_backend_name:"trillian"
        }
      Copy to clipboard

      添加 NEW_TREE_ID,并将 CHANGE_ME 替换为新私钥密码。此处的密码必须与用于生成新私钥和公钥的密码匹配。

      重要

      not_after_start 字段定义时间戳范围的开头。这意味着日志此时将开始接受证书。

  11. 创建新 secret 资源:

    Example

    $ oc create secret generic ctlog-config \
    --from-file=config=config.txtpb \
    --from-file=private=new-ctlog.pass.pem \
    --from-file=public=new-ctlog-public.pem \
    --from-file=fulcio-0=fulcio-0.pem \
    --from-file=private-0=private.pem \
    --from-file=public-0=public.pem \
    --from-literal=password=CHANGE_ME
    Copy to clipboard

    使用新私钥密码替换 CHANGE_ME

  12. 配置更新框架(TUF)服务,以使用新的 CT 日志公钥。

    1. 设置 shell 环境:

      Example

      $ export WORK="${HOME}/trustroot-example"
      $ export ROOT="${WORK}/root/root.json"
      $ export KEYDIR="${WORK}/keys"
      $ export INPUT="${WORK}/input"
      $ export TUF_REPO="${WORK}/tuf-repo"
      $ export TUF_SERVER_POD="$(oc get pod --selector=app.kubernetes.io/component=tuf --no-headers -o custom-columns=":metadata.name")"
      Copy to clipboard

    2. 创建临时 TUF 目录结构:

      Example

      $ mkdir -p "${WORK}/root/" "${KEYDIR}" "${INPUT}" "${TUF_REPO}"
      Copy to clipboard

    3. 将 TUF 内容下载到临时 TUF 目录结构中:

      Example

      $ oc extract --to "${KEYDIR}/" secret/tuf-root-keys
      $ oc cp "${TUF_SERVER_POD}:/var/www/html" "${TUF_REPO}"
      $ cp "${TUF_REPO}/root.json" "${ROOT}"
      Copy to clipboard

    4. 查找活跃的 CT 日志公钥文件名。在本地 TUF 存储库中打开最新的目标文件,例如 1.targets.json。在此目标文件中,您将找到活跃的 CT 日志公钥文件名,例如 ctfe.pub。使用这个活跃 CT 日志公钥文件名设置环境变量:

      Example

      $ export ACTIVE_CTFE_NAME=ctfe.pub
      Copy to clipboard

    5. 从 OpenShift 中提取活跃的 CT 日志公钥:

      Example

      $ oc get secret $(oc get ctlog securesign-sample -o jsonpath='{.status.publicKeyRef.name}') -o jsonpath='{.data.public}' | base64 -d > $ACTIVE_CTFE_NAME
      Copy to clipboard

    6. 使旧的 CT 日志签名者密钥过期:

      Example

      $ tuftool rhtas \
        --root "${ROOT}" \
        --key "${KEYDIR}/snapshot.pem" \
        --key "${KEYDIR}/targets.pem" \
        --key "${KEYDIR}/timestamp.pem" \
        --set-ctlog-target "$ACTIVE_CTFE_NAME" \
        --ctlog-uri "https://ctlog.rhtas" \
        --ctlog-status "Expired" \
        --outdir "${TUF_REPO}" \
        --metadata-url "file://${TUF_REPO}"
      Copy to clipboard

    7. 添加新的 CT 日志签名器密钥:

      Example

      $ tuftool rhtas \
        --root "${ROOT}" \
        --key "${KEYDIR}/snapshot.pem" \
        --key "${KEYDIR}/targets.pem" \
        --key "${KEYDIR}/timestamp.pem" \
        --set-ctlog-target "new-ctlog-public.pem" \
        --ctlog-uri "https://ctlog.rhtas" \
        --outdir "${TUF_REPO}" \
        --metadata-url "file://${TUF_REPO}"
      Copy to clipboard

    8. 将这些更改上传到 TUF 服务器:

      Example

      $ oc rsync "${TUF_REPO}/" "${TUF_SERVER_POD}:/var/www/html"
      Copy to clipboard

    9. 删除工作目录:

      Example

      $ rm -r $WORK
      Copy to clipboard

  13. 使用新树标识符更新 Securesign CT 日志配置:

    Example

    $ read -r -d '' SECURESIGN_PATCH <<EOF
    [
    	{
        	"op": "replace",
        	"path": "/spec/ctlog/serverConfigRef",
        	"value": {"name": "ctlog-config"}
    	},
        {
            "op": "replace",
            "path": "/spec/ctlog/treeID",
            "value": $NEW_TREE_ID
        },
    	{
        	"op": "replace",
        	"path": "/spec/ctlog/privateKeyRef",
        	"value": {"name": "ctlog-config", "key": "private"}
    	},
        {
            "op": "replace",
            "path": "/spec/ctlog/privateKeyPasswordRef",
            "value": {"name": "ctlog-config", "key": "password"}
        },
    	{
        	"op": "replace",
        	"path": "/spec/ctlog/publicKeyRef",
        	"value": {"name": "ctlog-config", "key": "public"}
    	}
    ]
    EOF
    Copy to clipboard

  14. Securesign 实例进行补丁:

    Example

    $ oc patch Securesign securesign-sample --type='json' -p="$SECURESIGN_PATCH"
    Copy to clipboard

  15. 等待 CT 日志服务器重新部署:

    Example

    $ oc wait pod -l app.kubernetes.io/name=ctlog --for=condition=Ready
    Copy to clipboard

  16. 使用更新的 TUF 配置更新 cosign 配置:

    Example

    $ cosign initialize --mirror=$TUF_URL --root=$TUF_URL/root.json
    Copy to clipboard

    现在,您已准备好使用新的 CT 日志签名器密钥签名并验证您的工件。

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat, Inc.