מקבל תעודות מזהות מ-Google Wallet

באינטרנט

אפשר לקבל תעודות מזהות דיגיטליות גם בתהליכים בתוך האפליקציה וגם בתהליכים באינטרנט. כדי לאשר את פרטי הכניסה מ-Google Wallet, צריך:

  1. מבצעים אינטגרציה דרך האפליקציה או האתר לפי ההוראות שסופקו,
  2. יש למלא את הטופס הזה כדי לבקש את התנאים וההגבלות לקבלת פרטי הכניסה מ-Google Wallet, ולאשר אותם.

דרישות מוקדמות

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

  • קישור לתנאים ולהגבלות
  • לוגו
  • אתר
  • מזהה החבילה בחנות Play (בשילובים עם אפליקציות ל-Android)
  • מזהה Gmail ששימש להצטרפות לגרסת הבטא הציבורית

פורמטים נתמכים של פרטי כניסה

יש כמה הצעות לסטנדרטים שמגדירים את פורמט הנתונים של מסמכי זהות דיגיטליים, ושניים מהם צברו תאוצה משמעותית בתעשייה:

  1. mdocs – מוגדר על ידי ISO.
  2. W3C Verifiable Credentials – מוגדרים על ידי W3C.

'מנהל פרטי הכניסה של Android' תומך בשני הפורמטים, אבל כרגע Google Wallet תומך רק בתעודות מזהות דיגיטליות שמבוססות על mdoc.

חוויית משתמש

כשאפליקציה מבקשת מאפייני זהות, מתרחש התהליך הבא:

  1. גילוי פרטי כניסה: האפליקציה שולחת שאילתות לארנקים הזמינים כדי לזהות פרטי כניסה שיכולים לענות על הבקשה. לאחר מכן, מערכת Android מציגה בורר של ממשק המשתמש של המערכת, שבו מוצג המידע שרוצים לשתף. כך המשתמש יכול לקבל החלטה מושכלת לגבי פרטי הכניסה שבהם הוא רוצה להשתמש.

  2. בחירה של המשתמש ואינטראקציה עם ארנק: המשתמש בוחר פרטי כניסה, ומערכת Android מפעילה את אפליקציית הארנק המתאימה כדי להשלים את העסקה. יכול להיות שתוצג באפליקציית Wallet בקשת הסכמה משלה או שתתבקשו לאשר את הבקשה באמצעות זיהוי ביומטרי.

תוצאה: אם המשתמש נותן הסכמה, פרטי הכניסה לזהות שנבחרו משותפים עם האפליקציה המבקשת. אם המשתמש דוחה את הבקשה, תוחזר שגיאה.

באפליקציה

כדי לבקש פרטי כניסה לזיהוי מאפליקציות ל-Android:

עדכון יחסי התלות

בקובץ build.gradle של הפרויקט, מעדכנים את יחסי התלות כך שישתמשו ב-Credential Manager (בטא):

dependencies {
    implementation("androidx.credentials:credentials:1.5.0-beta01")
    // optional - needed for credentials support from play services, for devices running Android 13 and below.
    implementation("androidx.credentials:credentials-play-services-auth:1.5.0-beta01")
}

הגדרת Credential Manager

כדי להגדיר ולאתחל אובייקט CredentialManager, מוסיפים לוגיקה דומה לזו:

// Use your app or activity context to instantiate a client instance of CredentialManager.
val credentialManager = CredentialManager.create(context)

מאפייני זהות של בקשות

במקום לציין פרמטרים נפרדים לבקשות אימות הזהות, האפליקציה מספקת את כולם יחד כמחרוזת JSON בתוך CredentialOption. מנהל פרטי הכניסה מעביר את מחרוזת ה-JSON הזו לארנקים הדיגיטליים הזמינים בלי לבדוק את התוכן שלה. לאחר מכן, כל ארנק אחראי על: - ניתוח מחרוזת ה-JSON כדי להבין את בקשת הזהות. - לקבוע אילו פרטי כניסה מאוחסנים, אם בכלל, עומדים בדרישות הבקשה.

צפוי ש-W3C יגדיר באופן רשמי את המבנה של בקשת ה-JSON הזו כחלק מפרט ה-API של האינטרנט. עם זאת, חשוב לזכור שהמפרט נמצא עדיין בטיוטא וכפוף לשינויים.

בשלב הראשון, נשתמש בפרוטוקול התצוגה המקדימה כדי לקבל תעודות מזהות מ-Google Wallet. כך נוכל להתחיל בשילוב ובבדיקה בזמן שאנחנו מסיימים את הגדרת המפרט של ה-API לאינטרנט.

דוגמה ל-mdoc requestJson לפרוטוקול התצוגה המקדימה:

{
  identity: {
    providers: [{
      holder: {
        selector: {
          format: ['mdoc'],
          type: 'org.iso.18013.5.1.mDL',
          fields: [
            'org.iso.18013.5.1.family_name',
            'org.iso.18013.5.1.portrait',
          ]
        },
        params: {
          nonce: '1234',
          readerPublicKey: '<public_key>',
          extraParamAsNeededByWallets: true,
        },
      },
    }]
  }
}
// The request in the JSON format to conform with
// the JSON-ified Digital Credentials API request definition.
val requestJson = generateRequestFromServer()
val digitalCredentialOption =
    GetDigitalCredentialOption(requestJson = requestJson)

// Use the option from the previous step to build the `GetCredentialRequest`.
val getCredRequest = GetCredentialRequest(
    listOf(digitalCredentialOption)
)

coroutineScope.launch {
    try {
        val result = credentialManager.getCredential(
            context = activityContext,
            request = getCredRequest
        )
        verifyResult(result)
    } catch (e : GetCredentialException) {
        handleFailure(e)
    }
}

// Handle the successfully returned credential.
fun verifyResult(result: GetCredentialResponse) {
    val credential = result.credential
    when (credential) {
        is DigitalCredential -> {
            val responseJson = credential.credentialJson
            validateResponseOnServer(responseJson)
        }
        else -> {
            // Catch any unrecognized credential type here.
            Log.e(TAG, "Unexpected type of credential ${credential.type}")
        }
    }
}

// Handle failure.
fun handleFailure(e: GetCredentialException) {
  when (e) {
        is GetCredentialCancellationException -> {
            // The user intentionally canceled the operation and chose not
            // to share the credential.
        }
        is GetCredentialInterruptedException -> {
            // Retry-able error. Consider retrying the call.
        }
        is NoCredentialException -> {
            // No credential was available.
        }
        is CreateCredentialUnknownException -> {
            // An unknown, usually unexpected, error has occurred. Check the
            // message error for any additional debugging information.
        }
        is CreateCredentialCustomException -> {
            // You have encountered a custom error thrown by the wallet.
            // If you made the API call with a request object that's a
            // subclass of CreateCustomCredentialRequest using a 3rd-party SDK,
            // then you should check for any custom exception type constants
            // within that SDK to match with e.type. Otherwise, drop or log the
            // exception.
        }
        else -> Log.w(TAG, "Unexpected exception type ${e::class.java}")
    }
}

התגובה מחזירה identityToken (מחרוזת JSON) שמוגדר על ידי W3C. אפליקציית Wallet אחראית ליצירת התגובה הזו.

דוגמה:

{
    "token": "<base64 encoded response>"
}

שליחת הטוקן ועיבוד שלו בשרת

לאחר קבלת identityToken, האפליקציה צריכה להעביר אותו לשרת האפליקציות לצורך אימות. השלב הראשון הוא פענוח האסימון מפורמט base64. מערך הבייטים שנוצר מייצג את נתוני ה-CBOR, שתואמים ל-CDDL הבא.

CredentialDocument = {
  "version": tstr,       // Set to "ANDROID-HPKE-v1"
  "pkEm": bstr,          // Public key, in uncompressed form
  "cipherText": bstr     // The encrypted data
}

השלב הבא הוא לחשב את SessionTranscript לפי תקן ISO/IEC 18013-5:2021 עם מבנה העברה ספציפי ל-Android:

SessionTranscript = [
  null,                // DeviceEngagementBytes not available
  null,                // EReaderKeyBytes not available
  AndroidHandover      // Defined below
]

AndroidHandover = [
  "AndroidHandoverv1", // Version number
  nonce,               // nonce that comes from request
  appId,               // RP package name
  pkRHash,             // The SHA256 hash of the recipient public key
]

הטקסט המוצפן cipherText מוצפן באמצעות הצפנת HPKE. כדי לפענח אותו, צריך להשתמש ב-SessionTranscript בתור הנתונים המאומתים הנוספים, יחד עם המפתח הפרטי של EC שנוצר קודם, וההגדרות הבאות:

  • KEM: ‏ DHKEM‏(P-256, ‏ HKDF-SHA256)
  • KDF: ‏ HKDF-SHA256
  • AEAD: ‏ AES-128-GCM

הטקסט ללא הצפנה שנוצר הוא הבייטים של DeviceResponse ב-CBOR כפי שהם מוגדרים ב-ISO/IEC 18013-5:2021. צריך לאמת את DeviceResponse בהתאם לסעיף 9 בתקן ISO/IEC 18013-5:2021. התהליך כולל כמה שלבים, כמו אימות שה-mdoc מגיע ממנפיק מהימן ושהתשובה חתומה על ידי המכשיר המיועד. אפשר להשתמש בכיתה DeviceResponseParser מפרויקט OpenWallet Foundation Identity Credential כחלק מתהליך האימות הזה.

פיתוח אתרים

כדי לבקש פרטי כניסה לזיהוי באמצעות Digital Credentials API ב-Chrome, צריך להירשם לגרסת המקור לניסיון של Digital Credentials API.

פנים אל פנים

כדי לקבל תעודות מזהות מ-Google Wallet, צריך לבצע את הפעולות הבאות:

  • פיתוח או רכישה של קורא שמקבל תעודות מזהות כפי שמוגדרות בתקן ISO 18013-5
  • טוענים לקורא אישורי IACA כדי לוודא שהתעודות המזוהות אותנטיות
  • בדיקת הפתרון
  • רישום האפליקציה ב-Google Wallet

פיתוח או רכישה של קורא שמקבל תעודות מזהות כפי שמוגדרות בתקן ISO 18013-5

התעודות המזהות ב-Wallet מיושמות בהתאם לתקן ISO 18013-5 לרישיונות נהיגה בנייד. הם משתמשים באינטראקציה מבוססת-NFC או בקוד QR בשילוב עם BLE כמנגנון להעברת נתונים – כך שכל מכשיר שיכול ליישם את ההיבטים האלה של התקן יכול לשמש כקורא, גם אפליקציה לנייד. מכיוון שהתקן פתוח, יש כמה הטמעות של צד שלישי שזמינות בשוק. בנוסף, אפשר להטמיע את הפונקציונליות ישירות לפי הצורך.

לקבלת הנחיות להטמעת הפונקציונליות בעצמכם, תוכלו להיעזר באפליקציה שלנו לקריאת מסמכים בקוד פתוח ל-Android, שמטמיעה את תקן ה-ISO ויכולה לקבל מסמכי mDL מ-Google Wallet.

כדי להתחיל, אפשר ליצור ולהריץ את אפליקציית קורא ההפניות:

  • שכפול של המאגר של אפליקציות העזר
  • פותחים את הפרויקט ב-Android Studio.
  • יוצרים ומפעילים את היעד appverifier במכשיר Android או במהדמ.

טוענים לקורא אישורי IACA כדי לוודא שהתעודות המזוהות אותנטיות

כדי לאמת פרטי כניסה אמיתיים, צריך להוסיף לארנק תעודה מזהה ממנפיק נתמך. בהמשך מופיעה רשימה של מנפיקים שנתמכים ב-Google Wallet, יחד עם קישורים לאישורים שלהם לאימות.

כדי לבדוק את הפתרון, צריך ליצור ולהריץ את אפליקציית Android שלנו, שמשמשת כחומר עזר בקוד פתוח. כך יוצרים ומפעילים את האפליקציה של בעל ההפניה:

  • שכפול של המאגר של אפליקציות העזר
  • פותחים את הפרויקט ב-Android Studio.
  • יוצרים ומפעילים את היעד appholder במכשיר Android או במהדמ.

(אופציונלי) רישום האפליקציה ב-Google Wallet

כדי לרשום את האפליקציה ב-Google Wallet, ממלאים את הטופס הזה.