בתהליך רגיל של הנפקת אישורים דיגיטליים באמצעות מפרט OpenID להנפקת אישורים ניתנים לאימות (OpenID4VCI), המנפיק צריך לדעת שהמפתח באישור שצריך לחתום עליו מאוחסן במיקום מאובטח. android_keystore_attestation סוג ההוכחה – פורמט לשימוש עם OpenID4VCI – מספק דוח חתום בחומרה ממאגר המפתחות של Android, כדי לוודא שהמפתח נעול בסביבת ביצוע מהימנה (TEE) או ב-StrongBox, ואי אפשר לייצא או לשכפל אותו.
סקירה כללית על אימות חומרה
כשמפתח נוצר ב-Android Keystore, המערכת יכולה ליצור אישור אימות. האישור הזה חתום על ידי מפתח שמוגן על ידי החומרה של המכשיר, שמתקשר חזרה ל-Root of Trust שנמצא בבעלות Google.
ההוכחה android_keystore_attestation היא מערך של שרשראות אישורים מסוג X.509. כל שרשרת מייצגת מפתח אימות יחיד ומובנית על ידי אישור עלים שאחריו אישורים ביניים.
- אישור קצה: מכיל את המפתח ותוסף אימות ספציפי ל-Android.
- אישורי ביניים: מחברים את אישור הקצה לאישור הבסיס של Android.
שלבי האימות
הגורמים המנפיקים צריכים לבצע כמה אימותים של האישור.
- מחפשים בשרשרת את האישור שמכיל את תוסף האימות של Android (בדרך כלל אישור העלה). האישור הזה מכיל את נתוני האימות של המפתח שנוצר על ידי Android Keystore.
- כדי למנוע מתקפות שידור חוזר, צריך לוודא שהשדה
attestationChallengeבתוסף זהה לערךc_nonceשסופק על ידי הפרוטוקול.
- בודקים את הערך של כל הטענות בתוספים שמעניינים אתכם.
- ביצוע בדיקת ביטול מול האישורים של מאגר המפתחות של Android.
הערכים בהוכחת האישור מגיעים מכמה מקורות:
- הנפקן: הנפקן מספק ערכים שונים, והנפוצים ביותר מופיעים בפורמט המטא-נתונים של הנפקן כדי לאפשר סינון בהצגה.
- הבעלים: ערכים כמו שם החבילה והחתימה מגיעים מהבעלים. הם לא משותפים באמצעות תהליכי הנפקה רגילים, וצריך לקבל אותם בנפרד מהמחזיק.
- פרוטוקול: ערכים כמו nonce עם
attestationChallengeמגיעים מהפרוטוקול.
הוראות מלאות יותר לאימות נתוני האישור זמינות במקורות המידע הבאים:
- אימות של צמדי מפתחות בגיבוי חומרה באמצעות אימות מפתחות
- פורמט של תוסף אימות מפתח ומזהה
- ספריית אימות עם מפתח
הפורמט של הוכחת האימות (Attestation)
בדוגמה הבאה מוצגת בקשה להענקת הרשאה שכוללת את android_keystore_attestationההוכחה:
{
"type": "array",
"description": "An array of certificate chains. Each chain attests a single key.",
"items": {
"type": "array",
"description": "An X.509 certificate chain. Each certificate is a Base64-encoded string. The first element in the chain is the leaf certificate with the extension, the last is the Android Keystore root certificate.",
"items": {
"type": "string",
"description": "A single X.509 certificate (Base64-NoWrap padded DER encoded)."
},
"minItems": 1
},
"minItems": 1
}
הוא נשמר באובייקט proofs של בקשת פרטי הכניסה.
{
"credential_configuration_id": "org.iso.18013.5.1.mDL",
"proofs": {
"android_keystore_attestation": [
[
"MII...", // Leaf certificate (contains Keystore extension)
"MII...", // Intermediate certificate
"MII..." // Android Root certificate
],
[ "MII...", "MII...", "MII..." ] // second proof
]
}
}
פורמט מטא-נתונים של מנפיק
המנפיק מציין את סוגי ההוכחות שהוא תומך בהם על ידי הכללת האובייקט android_keystore_attestation בתוך האובייקט proof_types_supported עבור הגדרת אישורים נתונה.
זו דוגמה לאובייקט android_keystore_attestation של מנפיקים:
{
"type": "object",
"properties": {
"proof_signing_alg_values_supported": {
"type": "array",
"description": "REQUIRED. As defined in OpenID4VCI 1.0 Section 12.2.4.",
"items": {
"type": "string",
"description": "Cryptographic algorithm identifiers used in the proof_signing_alg_values_supported Credential Issuer metadata parameter for this proof type are case sensitive strings and SHOULD be one of those defined in [IANA.JOSE]."
},
"minItems": 1
},
"key_attestations_required": {
"type": "object",
"description": "OPTIONAL. Specifies the minimum attestation requirements.",
"properties": {
"key_mint_security_level": {
"type": "string",
"description": "OPTIONAL. Minimum accepted keyMintSecurityLevel. Values defined in https://source.android.com/docs/security/features/keystore/attestation#securitylevel-values.",
"enum": ["Software", "TrustedEnvironment", "StrongBox"],
"default": "TrustedEnvironment"
},
"user_auth_types": {
"type": "array",
"description": "OPTIONAL. A list of authentication types which can authorize the use of the key. If empty, no authentication is required. If multiple, any are allowed.",
"items": {
"type": "string",
"description": "Allowed values are 'LSKF' and 'BIOMETRIC'. These values are meant to mimic the values used during the key generation process here.",
"enum": ["LSKF", "BIOMETRIC"]
},
"default": []
}
}
}
},
"required": ["proof_signing_alg_values_supported"]
}
זו דוגמה לאובייקט החיצוני proof_types_supported:
{
"credential_configurations_supported": {
"org.iso.18013.5.1.mDL": {
"format": "mso_mdoc",
"doctype": "org.iso.18013.5.1.mDL",
"cryptographic_binding_methods_supported": [
"cose_key"
],
"credential_signing_alg_values_supported": [
-7, -9
],
"proof_types_supported": {
"android_keystore_attestation": {
"proof_signing_alg_values_supported": [
"ES256" // ecdsaWithSHA256
],
"key_attestations_required" : {
// OPTIONAL String - Representing the minimum accepted value for keyMintSecurityLevel values
// defined here ("Software"|"TrustedEnvironment"|"StrongBox"). Default value: "TrustedEnvironment"
"key_mint_security_level": "TrustedEnvironment",
// OPTIONAL List of Strings - Representing all allowed values for userAuthType values defined here.
// [] value will represent noAuthRequired. Default value: [].
"user_auth_types": ["LSKF", "BIOMETRIC"]
}
}
}
}
}
}
מיפוי הצהרות אימות של VCI ל-Android Keystore
בטבלה הזו מוצגת מיפוי מידע שיעזור לגורמים שמכירים את סוג ההוכחה של אישור OpenID4VCI להבין איפה נמצאים מושגים דומים באישור של Android Keystore.
תלונה על אימות תאימות למדיניות (VCI) |
|
מיקום הערך הצפוי |
iss |
המפתח הציבורי של אישור הבסיס של מאגר המפתחות |
לא רלוונטי |
iat |
הערך |
לא רלוונטי |
exp |
השדה |
לא רלוונטי |
attested_keys |
מפתח ציבורי שכלול באישור העלה של כל שרשרת |
לא רלוונטי |
key_storage |
הערך |
הערך בשדה |
user_authentication |
|
הערך בשדה |
nonce |
הערך |
מפרוטוקול: הערך |
אישור |
לא רלוונטי |
לא רלוונטי |
status |
לא רלוונטי |
לא רלוונטי |