访问安全元数据并验证软件包

本页面介绍如何从 assuredoss-metadata Cloud Storage 存储桶访问安全元数据。如需了解安全元数据,请参阅安全元数据字段

本页面仅适用于 Assured OSS 付费层级。如需了解免费层级,请参阅在 Assured OSS 免费层级中验证签名

准备工作

设置身份验证

提取元数据

您可以使用 gsutilcurl 命令下载元数据。使用以下信息构建这两种方法的网址:

  • 语言javapythonjavascript。该值必须采用小写形式。
  • Package_ID::在 Java 中,它是 groupId:artifactId;在 Python 中,它是 packageName;在 JavaScript 中,它是 @org-name/package-name@username/package-namepackage-name 之一。该值必须采用小写形式。
  • 版本:软件包的版本。

该网址必须采用以下格式:

gsutil

gs://assuredoss-metadata/language/package_id/version/metadata.json

网址必须采用小写形式。

Python 网址示例:gs://assuredoss-metadata/python/blessed/1.20.0/metadata.json

示例 Java 网址:gs://assuredoss-metadata/java/org.apache.logging.log4j:log4j-core/2.17.1/metadata.json

JavaScript 网址示例:gs://assuredoss-metadata/javascript/@stoplight/spectral-core/0.0.0/metadata.json

curl

https://storage.googleapis.com/assuredoss-metadata/language/package_id/version/metadata.json

网址必须采用小写形式。

Python 网址示例:https://storage.googleapis.com/assuredoss-metadata/python/blessed/1.20.0/metadata.json

示例 Java 网址:https://storage.googleapis.com/assuredoss-metadata/java/org.apache.logging.log4j:log4j-core/2.17.1/metadata.json

JavaScript 网址示例:https://storage.googleapis.com/assuredoss-metadata/javascript/@stoplight/spectral-core/0.0.0/metadata.json

  1. 下载元数据:

gsutil

gsutil -m cp  "gs://assuredoss-metadata/language/package_id/version/metadata.json" outputFolderLocation

curl

curl -H "Authorization: Bearer $(gcloud auth print-access-token)" -L https://storage.googleapis.com/assuredoss-metadata/language/package_id/version/metadata.json -o metadata.json

您现在可以验证签名了。具体有两种方案可供选择:

使用 aoss-verifier 工具验证所下载软件包的签名

使用 aoss-verifier 工具验证软件包元数据。

在使用此工具之前,请先安装 Go

  1. 安装 aoss-verifier 工具。

  2. 导出 $(go env GOPATH)/bin

  3. 运行 aoss-verifier verify-metadata 命令。

    aoss-verifier verify-metadata \
       --metadata_type TYPE \
       --language LANGUAGE \
       --package_id PACKAGE_ID \
       --version VERSION \
       [--disable_certificate_verification] \
       [--temp_downloads_path TEMP_DOWNLOADS_DIR_PATH] \
       [--disable_deletes]
    

    请替换以下内容:

    • TYPE:可能的值为 premiuminfo
    • LANGUAGE:软件包语言。 该值必须采用小写形式。
    • PACKAGE_ID:对于 Java,格式为 groupId:artifactId。对于 Python,格式为 packageName。该值必须采用小写形式。
    • VERSION:软件包的版本。

    --disable_certificate_verification 是一个可选标志,用于跳过将叶证书匹配到通过证书链的根证书(如果使用了此标志)。

    --temp_downloads_path 是一个可选标志,用于设置要在其中下载文件的路径(替换 TEMP_DOWNLOADS_DIR_PATH)。如果未设置此标志,系统会将文件下载到当前目录中的 tmp_downloads 文件夹中。

    --disable_deletes 是一个可选标志,用于保存已下载的文件。默认情况下,该工具会清理所有已下载的文件。

如需了解详情,请参阅自述文件

手动验证所下载软件包的签名

您只能验证由 Assured OSS 安全构建的二进制文件(而非由 Assured OSS 通过代理提供的二进制文件)的工件签名。

如需手动验证签名,您可以使用各种工具。以下步骤使用 gcloud CLI、OpenSSL(3.0.1 或更高版本)和 jq(1.7.1 或更高版本)在 Linux 上验证签名。

  1. 下载元数据文件。如使用 Cloud Storage 访问元数据中所述,元数据文件的 buildInfo 字段内包含一个 SBOM 字段。SBOM 包含与表示签名的注解一起构建的工件(例如,JAR 或 EGG 文件)。您可以通过此工件确定 SPDX ID。

    例如,如果工件名称为 artifact_name,则 spdx_idSPDXRef-Package-artifact_name。如需验证名为 gradio-3.30.0-py3-none-any.whl 的软件包,spdx_idSPDXRef-Package-gradio-3.30.0-py3-none-any.whl

  2. 从元数据文件中提取 SHA-256 摘要:

    cat METADATA_FILENAME | jq -rj '.buildInfo' | jq -rj '.sbom' | jq -rj '.packages' | jq '.[] | select(.SPDXID=="SPDX_ID")' | jq -rj '.annotations[0].comment' | jq -rj '.digest[0].digest' | cut -d ' ' -f1 > expectedDigest.txt
    

    请替换以下内容:

    • METADATA_FILENAME:安全元数据文件的名称。

    • SPDX_ID:SPDX 标识符。

  3. 计算工件摘要:

    sha256sum ARTIFACT_FILE | cut -d ' ' -f1 > actualDigest.txt
    

    ARTIFACT_FILE 替换为工件文件的名称。

  4. 检查两者之间是否存在任何差异:

    diff actualDigest.txt expectedDigest.txt
    

    如果没有差异,则没有输出。

  5. 将该字段的摘要提取到 .bin 文件中:

    cat METADATA_FILENAME | jq -rj '.buildInfo' | jq -rj '.sbom' | jq -rj '.packages' | jq '.[] | select(.SPDXID=="SPDX_ID")' | jq -rj '.annotations[0].comment' | jq -rj '.digest[0].digest' | cut -d ':' -f2 | xxd -r -p > digest.bin
    
  6. 将摘要的签名提取到 .sig 文件中:

    cat METADATA_FILENAME | jq -rj '.buildInfo' | jq -rj '.sbom' | jq -rj '.packages' | jq '.[] | select(.SPDXID=="SPDX_ID")' | jq -rj '.annotations[0].comment' | jq -rj '.signature[0].signature' | xxd -r -p > sig.sig
    
  7. 将公共证书提取到 .pem 文件中:

    cat METADATA_FILENAME | jq -rj '.buildInfo' | jq -rj '.sbom' | jq -rj '.packages' | jq '.[] | select(.SPDXID=="SPDX_ID")' | jq -rj '.annotations[0].comment' | jq -rj '.certInfo.cert' | openssl x509 -pubkey -noout  > pubKey.pem
    
  8. 使用证书验证摘要的签名:

    openssl pkeyutl -in digest.bin -inkey pubKey.pem -pubin -verify -sigfile sig.sig
    

    如果成功,此命令将返回 Signature Verified Successfully。 现在,您可以验证证书了。

  9. 将公共证书链解压缩到 .pem 文件中:

    cat METADATA_FILENAME | jq -rj '.buildInfo' | jq -rj '.sbom' | jq -rj '.packages' | jq '.[] | select(.SPDXID=="SPDX_ID")' | jq -rj '.annotations[0].comment' | jq -rj '.certInfo.certChain' | openssl x509 -pubkey -noout  > pubKeyChain.pem
    
  10. 下载根证书(以下命令中的 ca.crt):

    curl -o ca.crt https://privateca-content-6333d504-0000-2df7-afd6-30fd38154590.storage.googleapis.com/a2c725a592f1d586f1f8/ca.crt
    
  11. 使用证书链和根证书验证证书:

    openssl verify -verbose -CAfile ca.crt -untrusted pubKeyChain.pem pubKey.pem
    

    如果成功,此命令将返回 pubKey.pem: OK

验证安全元数据字段的签名

您可以单独验证安全元数据文件中以下字段的签名:

  • buildInfo
  • vexInfo
  • healthInfo(如果存在)

这些字段中的数据使用 SHA-256 进行哈希处理,然后使用 ECDSAP256_DER 算法对哈希值进行签名。证书和证书链在元数据内提供,以便您验证签名。使用以下根证书来验证证书链:

https://privateca-content-6333d504-0000-2df7-afd6-30fd38154590.storage.googleapis.com/a2c725a592f1d586f1f8/ca.crt

您可以手动验证签名,也可以使用 Assured OSS 验证程序工具验证签名。

以下步骤介绍了如何手动验证 metadata.json 文件中 buildInfo 字段的签名。您可以使用类似的步骤来验证 vexInfo 字段或 healthInfo 字段的签名。

您可以使用各种工具验证签名。以下示例使用 gcloud CLI、OpenSSL(3.0.1 或更高版本)和 jq(1.7.1 或更高版本)验证 Linux 系统上的签名。

  1. 生成字段的 SHA-256 摘要:

    cat metadata.json | jq -rj '.buildInfo' | sha256sum | cut -d ' ' -f1 > actualDigest.txt
    
  2. 提取 metadata.json 文件中提供的字段摘要:

    cat metadata.json | jq -rj '.buildInfoSignature.digest[0].digest' | cut -d ':' -f2 > expectedDigest.txt
    
  3. 检查两个摘要之间是否存在任何差异:

    diff actualDigest.txt expectedDigest.txt
    

    如果没有差异,则不存在任何输出,这是理想情况。您现在可以验证签名了。

  4. 将该字段的摘要提取到 .bin 文件中:

    cat metadata.json | jq -rj '.buildInfoSignature.digest[0].digest' | cut -d ':' -f2 | xxd -r -p > digest.bin
    
  5. 将摘要的签名提取到 .sig 文件中:

    cat metadata.json | jq -rj '.buildInfoSignature.signature[0].signature' | xxd -r -p > sig.sig
    
  6. 将公共证书提取到 .pem 文件中:

    cat metadata.json | jq -rj '.buildInfoSignature.certInfo.cert' | openssl x509 -pubkey -noout  > pubKey.pem
    
  7. 使用证书验证摘要的签名:

    openssl pkeyutl -in digest.bin -inkey pubKey.pem -pubin -verify -sigfile sig.sig
    

    如果验证成功,此命令将返回 Signature Verified Successfully。现在,您可以验证证书了。

  8. 将公共证书提取到 .pem 文件中:

    cat metadata.json | jq -rj '.buildInfoSignature.certInfo.cert' | openssl x509 -pubkey -noout  > pubKey.pem
    
  9. 将公共证书链解压缩到 .pem 文件中:

    cat metadata.json | jq -rj '.buildInfoSignature.certInfo.certChain' | openssl x509 -pubkey -noout  > pubKeyChain.pem
    
  10. 在以下命令中下载名为 ca.crt 的根证书:

    curl -o ca.crt https://privateca-content-6333d504-0000-2df7-afd6-30fd38154590.storage.googleapis.com/a2c725a592f1d586f1f8/ca.crt
    
  11. 使用证书链和根证书验证证书:

    openssl verify -verbose -CAfile ca.crt -untrusted pubKeyChain.pem pubKey.pem
    

    如果成功,该命令将返回 pubKey.pem: OK