存取安全性中繼資料並驗證套件

Assured Open Source Software (Assured OSS) 會為每個可用的套件和套件版本提供安全性中繼資料。您可以在 assuredoss-metadata Cloud Storage bucket 中存取這項中繼資料,查看建構作業詳細資料、安全漏洞狀態、測試結果和授權資訊。如需安全性中繼資料的說明,請參閱「安全性中繼資料欄位」。

本文僅適用於 Assured OSS 進階級。如需免費方案,請參閱「在 Assured OSS 免費方案中驗證簽章」。

事前準備

  1. 將 Assured OSS 與 Security Command Center 整合。

  2. 驗證所要求服務帳戶與 Assured OSS 的連線能力。

擷取中繼資料

您可以使用 gcloud 或 curl 指令下載中繼資料。請使用下列資訊建構兩者的網址:

  • 語言:java、python、golang 或 javascript。值必須為小寫。
  • Package_ID:下列其中一項:

    • Java:groupId:artifactId
    • Python:packageName
    • JavaScript (NPM):@scope/package-name 或 package-name
    • Go:packageName

    值必須為小寫。

  • 版本:套件的版本。

網址必須採用下列格式:

gcloud

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

  • Go 網址範例:gs://assuredoss-metadata/golang/github.com/rs/zerolog/1.9.1/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

  • Go 網址範例:https://storage.googleapis.com/assuredoss-metadata/golang/github.com/rs/zerolog/1.9.1/metadata.json

  1. 下載中繼資料:

gcloud

gcloud storage 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 和 Go 的格式為 packageName。如果是 JavaScript (NPM),格式為 @scope/package-name 或 package-name。值必須為小寫。
    • VERSION:套件版本。

    --disable_certificate_verification 是選用旗標,如果使用,則會略過透過憑證鏈結將分葉憑證與根憑證比對的步驟。

    --temp_downloads_path 是選用旗標,用於設定要下載檔案的路徑 (取代 TEMP_DOWNLOADS_DIR_PATH)。如未設定旗標,檔案會下載到目前目錄中的 tmp_downloads 資料夾。

    --disable_deletes 是選用旗標,可保留下載的檔案。根據預設,這項工具會清除所有下載的檔案。

詳情請參閱 README。

手動驗證下載套件的簽章

您只能驗證由 Assured OSS 安全建構的二進位檔構件簽章,無法驗證 Assured OSS 透過 Proxy 提供的二進位檔。

如要手動驗證簽名,可以使用各種工具。下列步驟使用 gcloud CLI、OpenSSL (3.0.1 以上版本) 和 jq (1.7.1 以上版本),在 Linux 上驗證簽章。

  1. 下載中繼資料檔案。 如「安全性中繼資料欄位」一節所述,中繼資料檔案在 buildInfo 欄位中包含 SBOM 欄位。SBOM 包含建構的構件 (例如 JAR 或 EGG 檔案),以及代表簽章的註解。這個構件可讓您判斷 SPDX ID。

    舉例來說,如果構件名稱為 artifact_name,則 spdx_id 為 SPDXRef-Package-artifact_name。如要驗證名為 gradio-3.30.0-py3-none-any.whl 的套件,spdx_id 為 SPDXRef-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 ID。

  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.cert' > cert.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 cert.pem
    

    如果成功,這個指令會傳回 cert.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' > cert.pem
    
  9. 下載根憑證,在下列指令中名為 ca.crt:

    curl -o ca.crt https://privateca-content-6333d504-0000-2df7-afd6-30fd38154590.storage.googleapis.com/a2c725a592f1d586f1f8/ca.crt
    
  10. 使用擷取的憑證和根憑證驗證憑證:

    openssl verify -verbose -CAfile ca.crt cert.pem
    

    如果成功,指令會傳回 cert.pem: OK。