גישה למטא-נתונים של אבטחה ואימות חבילות

במאמר הזה מוסבר איך לגשת למטא-נתוני אבטחה מassuredoss-metadata קטגוריה של Cloud Storage. תיאור של מטא-נתוני האבטחה מופיע במאמר שדות מטא-נתונים של אבטחה.

המסמך הזה רלוונטי רק למסלול הפרימיום Assured OSS. מידע על רמת השירות החינמית זמין במאמר אימות חתימות ברמת השירות החינמית של Assured OSS.

לפני שמתחילים

  1. שילוב של Assured OSS עם Security Command Center.

  2. מאמתים את הקישוריות אל Assured OSS עבור חשבונות השירות המבוקשים.

חילוץ המטא-נתונים

אפשר להשתמש בפקודות gcloud או curl כדי להוריד את המטא-נתונים. כדי לבנות את כתובת ה-URL לשני המקרים, משתמשים בפרטים הבאים:

  • שפה: java,‏ python,‏ golang או javascript. הערך חייב להיות באותיות קטנות.
  • Package_ID: אחת מהאפשרויות הבאות:

    • Java:‏ groupId:artifactId
    • Python:‏ packageName
    • ‫JavaScript: אחת מהאפשרויות הבאות: @org-name/package-name, @username/package-name או package-name
    • Go:‏ packageName

    הערך חייב להיות באותיות קטנות.

  • גרסה: גרסת החבילה.

כתובת ה-URL צריכה להיות בפורמט הבא:

gcloud

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

כתובת ה-URL צריכה להיות באותיות קטנות.

כתובות URL לדוגמה:

  • כתובת URL לדוגמה ב-Python: ‏ gs://assuredoss-metadata/python/blessed/1.20.0/metadata.json

  • כתובת URL לדוגמה ב-Java: ‏ gs://assuredoss-metadata/java/org.apache.logging.log4j:log4j-core/2.17.1/metadata.json

  • כתובת URL לדוגמה של JavaScript: ‏ gs://assuredoss-metadata/javascript/@stoplight/spectral-core/0.0.0/metadata.json

  • כתובת URL לדוגמה ב-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

כתובת ה-URL צריכה להיות באותיות קטנות.

כתובות URL לדוגמה:

  • כתובת URL לדוגמה ב-Python: ‏ https://storage.googleapis.com/assuredoss-metadata/python/blessed/1.20.0/metadata.json

  • כתובת URL לדוגמה ב-Java: ‏ https://storage.googleapis.com/assuredoss-metadata/java/org.apache.logging.log4j:log4j-core/2.17.1/metadata.json

  • כתובת URL לדוגמה של JavaScript: ‏ https://storage.googleapis.com/assuredoss-metadata/javascript/@stoplight/spectral-core/0.0.0/metadata.json

  • כתובת URL לדוגמה ב-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. הערך חייב להיות באותיות קטנות.
    • VERSION: הגרסה של החבילה.

    --disable_certificate_verification הוא דגל אופציונלי שגורם למערכת לדלג על ההתאמה בין אישור הקצה לאישור הבסיס דרך שרשרת האישורים, אם משתמשים בו.

    --temp_downloads_path הוא דגל אופציונלי להגדרת הנתיב שבו רוצים להוריד את הקבצים (צריך להחליף את TEMP_DOWNLOADS_DIR_PATH). אם הדגל לא מוגדר, הקבצים יורדים לתיקייה tmp_downloads בספרייה הנוכחית.

    --disable_deletes הוא דגל אופציונלי ששומר את הקבצים שהורדו. כברירת מחדל, הכלי מנקה את כל הקבצים שהורדו.

מידע נוסף זמין בREADME.

אימות ידני של החתימות של חבילות שהורדו

אפשר לאמת את חתימת הארטיפקט רק עבור הקבצים הבינאריים שנבנו בצורה מאובטחת על ידי Assured OSS, ולא עבור הקבצים שסופקו על ידי Assured OSS דרך שרתי proxy.

כדי לאמת חתימות באופן ידני, אפשר להשתמש בכלים שונים. בשלבים הבאים נעשה שימוש ב-CLI של gcloud, ב-OpenSSL (גרסה 3.0.1 ואילך) וב-jq (גרסה 1.7.1 ואילך) כדי לאמת את החתימות ב-Linux.

  1. הורדת קובץ המטא-נתונים. כמו שמתואר בשדות מטא-נתונים של אבטחה, קובץ המטא-נתונים מכיל שדה SBOM בתוך השדה buildInfo. ה-SBOM מכיל את הארטיפקט (לדוגמה, קובץ JAR או EGG) שנבנה יחד עם הערה שמייצגת את החתימה. הארטיפקט הזה מאפשר לכם לקבוע את מזהה SPDX.

    לדוגמה, אם שם הארטיפקט הוא 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.

  3. מחשבים את ה-digest של הארטיפקט:

    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. מחלצים את החתימה של ה-digest לקובץ .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. מאמתים את החתימה של ה-digest באמצעות המפתח הציבורי שחולץ:

    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 Verifier Tool).

בשלבים הבאים מוסבר איך לאמת ידנית את החתימה של השדה buildInfo בקובץ metadata.json. אפשר להשתמש בשלבים דומים כדי לאמת את החתימה של השדה vexInfo או של השדה healthInfo.

אפשר לאמת חתימות באמצעות כלים שונים. בדוגמה הבאה נעשה שימוש ב-CLI של gcloud, ב-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. מחפשים את ה-digest של השדה שמופיע בקובץ 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. מחלצים את החתימה של ה-digest לקובץ .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. מאמתים את החתימה של ה-digest באמצעות המפתח הציבורי שחולץ:

    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.