Les pièces d'identité numériques peuvent être acceptées dans les parcours in-app et Web. Pour accepter les identifiants Google Wallet, vous devez :
- Intégrez-le à l'aide de l'application ou du Web en suivant les instructions fournies.
- Utilisez l'ID de test pour tester votre flux à l'aide du bac à sable Google Wallet.
- Pour commencer à diffuser en direct, remplissez ce formulaire pour demander l'accès et accepter les conditions d'utilisation des identifiants Google Wallet. Vous devez remplir ce formulaire pour chacune de vos entités commerciales. Notre équipe vous contactera une fois que vous aurez rempli le formulaire.
- Si vous avez des questions, vous pouvez contacter
wallet-identity-rp-support@google.com
.
Formats d'identifiants acceptés
Il existe plusieurs normes proposées qui définissent le format de données des documents d'identité numérique, dont deux qui ont gagné en popularité dans le secteur :
- mdocs : définis par l'ISO.
- Informations d'identification vérifiables W3C : définies par le W3C.
Bien que le Gestionnaire d'identifiants Android soit compatible avec les deux formats, Google Wallet n'accepte pour le moment que les pièces d'identité numériques basées sur le format mdoc.
Identifiants acceptés
Google Wallet est compatible avec deux types d'identifiants :
- Permis de conduire mobile (mDL)
- Pass d'identité
Vous pouvez demander l'une ou l'autre des identifiants dans votre flux en modifiant un seul paramètre.
Expérience utilisateur
Cette section décrit le déroulement recommandé d'une présentation en ligne. Le flux montre la présentation de l'âge à une application de livraison d'alcool, mais l'UX est similaire pour le Web et d'autres types de présentations.
![]() |
![]() |
![]() |
![]() |
![]() |
L'utilisateur est invité à valider son âge dans l'application ou sur le site Web. | L'utilisateur voit les identifiants éligibles disponibles. | L'utilisateur voit une page de confirmation dans Google Wallet. | L'utilisateur s'authentifie pour confirmer le partage | Données envoyées à l'application ou au site Web |
Remarques importantes
- L'application ou le site Web peuvent créer le point d'entrée de l'API de différentes manières. Comme indiqué à l'étape 1, nous vous recommandons d'afficher un bouton générique tel que "Valider avec une pièce d'identité numérique", car nous prévoyons que d'autres options que Google Wallet seront disponibles via l'API au fil du temps.
- L'écran du sélecteur à l'étape 2 est affiché par Android. Les identifiants éligibles sont déterminés par une correspondance entre la logique d'enregistrement fournie par chaque portefeuille et la requête envoyée par la partie de confiance.
- L'étape 3 est affichée par Google Wallet. Google Wallet affichera le nom, le logo et les règles de confidentialité fournis par le développeur sur cet écran.
Ajouter un flux d'identité numérique
Si l'utilisateur ne possède pas de pièce d'identité, nous vous recommandons de fournir un lien à côté du bouton "Valider avec une pièce d'identité numérique" qui redirige vers Google Wallet pour lui permettre d'ajouter une pièce d'identité numérique.
![]() |
![]() |
L'utilisateur est invité à valider son âge dans l'application ou sur le site Web. | L'utilisateur est redirigé vers Google Wallet pour obtenir une pièce d'identité numérique. |
Aucune pièce d'identité numérique disponible
Si l'utilisateur sélectionne l'option "Valider avec une pièce d'identité numérique" sans en posséder une, le message d'erreur suivant s'affiche.
![]() |
![]() |
L'utilisateur est invité à valider son âge dans l'application ou sur le site Web. | Un message d'erreur s'affiche si l'utilisateur ne possède pas d'identité numérique. |
L'API n'est pas compatible avec une fonctionnalité permettant de savoir silencieusement si l'utilisateur dispose d'identifiants numériques disponibles, afin de préserver sa confidentialité. Nous vous recommandons donc d'inclure l'option de lien d'intégration, comme indiqué.
Format de la demande pour demander des identifiants au portefeuille
Voici un exemple de requête requestJson
mdoc permettant d'obtenir des identifiants d'identité à partir de n'importe quel portefeuille sur un appareil Android ou sur le Web.
{
"requests" : [
{
"protocol": "openid4vp",
"data": {<credential_request>} // This is an object, shouldn't be a string.
}
]
}
Demander le chiffrement
client_metadata
contient la clé publique de chiffrement pour chaque requête. Vous devrez stocker les clés privées pour chaque requête et les utiliser pour authentifier et autoriser le jeton que vous recevez de l'application Wallet.
Le paramètre credential_request
dans requestJson
comprend les champs suivants.
{
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "1234",
"dcql_query": {
"credentials": [
{
"id": "cred1",
"format": "mso_mdoc",
"meta": {
"doctype_value": "org.iso.18013.5.1.mDL" // this is for mDL. Use com.google.wallet.idcard.1 for ID pass
},
"claims": [
{
"path": [
"org.iso.18013.5.1",
"family_name"
],
"intent_to_retain": false // set this to true if you are saving the value of the field
},
{
"path": [
"org.iso.18013.5.1",
"given_name"
],
"intent_to_retain": false
},
{
"path": [
"org.iso.18013.5.1",
"age_over_18"
],
"intent_to_retain": false
}
]
}
]
},
"client_metadata": {
"jwks": {
"keys": [ // sample request encryption key
{
"kty": "EC",
"crv": "P-256",
"x": "pDe667JupOe9pXc8xQyf_H03jsQu24r5qXI25x_n1Zs",
"y": "w-g0OrRBN7WFLX3zsngfCWD3zfor5-NLHxJPmzsSvqQ",
"use": "enc",
"kid" : "1",
"alg" : "ECDH-ES",
}
]
},
"authorization_encrypted_response_alg": "ECDH-ES",
"authorization_encrypted_response_enc": "A128GCM"
}
}
Vous pouvez demander n'importe quel nombre d'attributs compatibles à partir de n'importe quel identifiant stocké dans Google Wallet.
Dans l'application
Pour demander des identifiants d'identité à vos applications Android, procédez comme suit :
Mettre à jour les dépendances
Dans le fichier build.gradle de votre projet, mettez à jour vos dépendances pour utiliser Credential Manager (bêta) :
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")
}
Configurer le Gestionnaire d'identifiants
Pour configurer et initialiser un objet CredentialManager
, ajoutez une logique semblable à celle-ci :
// Use your app or activity context to instantiate a client instance of CredentialManager.
val credentialManager = CredentialManager.create(context)
Demander des attributs d'identité
Au lieu de spécifier des paramètres individuels pour les demandes d'identité, l'application les fournit tous ensemble sous forme de chaîne JSON dans CredentialOption. Le Gestionnaire d'identifiants transmet cette chaîne JSON aux portefeuilles numériques disponibles sans examiner son contenu. Chaque portefeuille est ensuite responsable des éléments suivants : - Analyser la chaîne JSON pour comprendre la demande d'identité. - Déterminer lesquels de ses identifiants stockés, le cas échéant, répondent à la demande.
Nous recommandons aux partenaires de créer leurs requêtes sur le serveur, même pour les intégrations d'applications Android.
Vous utiliserez le requestJson
de Format de la requête, qui contient le request
dans l'appel de fonction GetDigitalCredentialOption()
.
// 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)
}
}
Vérifier et valider la réponse
Une fois que vous avez reçu une réponse du portefeuille, vérifiez si elle est positive et contient la réponse credentialJson
.
// Handle the successfully returned credential.
fun verifyResult(result: GetCredentialResponse) {
val credential = result.credential
when (credential) {
is DigitalCredential -> {
val responseJson = credential.credentialJson
validateResponseOnServer(responseJson) // make a server call to validate the response
}
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.
}
else -> Log.w(TAG, "Unexpected exception type ${e::class.java}")
}
}
La réponse credentialJson
contient un identityToken (JWT) chiffré, défini par le W3C. L'application Wallet est responsable de la création de cette réponse.
Exemple :
{
"protocol" : "openid4vp",
"data" : {
<encrpted_response>
}
}
Vous renverrez cette réponse au serveur pour valider son authenticité. Vous trouverez la procédure de validation de la réponse d'identifiant.
Web
Pour demander des identifiants à l'aide de l'API Digital Credentials sur Chrome, vous devez vous inscrire à la phase d'évaluation de l'origine de l'API Digital Credentials.
const credentialResponse = await navigator.credentials.get({
digital : {
requests : [
{
protocol: "openid4vp",
data: {<credential_request>} // This is an object, shouldn't be a string.
}
]
}
})
Renvoyez la réponse de cette API à votre serveur pour valider la réponse des identifiants.
Étapes à suivre pour valider la réponse des identifiants
Lorsque vous recevez le identityToken chiffré de votre application ou de votre site Web, vous devez effectuer plusieurs validations avant de faire confiance à la réponse.
Déchiffrer la réponse à l'aide d'une clé privée
La première étape consiste à déchiffrer le jeton à l'aide de la clé privée enregistrée et à obtenir un JSON de réponse.
Exemple Python :
from jwcrypto import jwe, jwk # Retrieve the Private Key from Datastore reader_private_jwk = jwk.JWK.from_json(jwe_private_key_json_str) # Decrypt the JWE encrypted response from Google Wallet jwe_object = jwe.JWE() jwe_object.deserialize(encrypted_jwe_response_from_wallet) jwe_object.decrypt(reader_private_jwk) decrypted_payload_bytes = jwe_object.payload decrypted_data = json.loads(decrypted_payload_bytes)
decrypted_data
génère un fichier JSONvp_token
contenant les identifiants.{ "vp_token": { "cred1": "<credential_token>" } }
Créer la transcription de la session
L'étape suivante consiste à créer le SessionTranscript à partir de la norme ISO/IEC 18013-5:2021 avec une structure de transfert spécifique à Android ou au Web :
SessionTranscript = [ null, // DeviceEngagementBytes not available null, // EReaderKeyBytes not available [ "OpenID4VPDCAPIHandover", AndroidHandoverDataBytes // BrowserHandoverDataBytes for Web ] ]
Pour les transferts Android / Web, vous devez utiliser le même nonce que celui utilisé pour générer
credential_request
.Transfert Android
AndroidHandoverData = [ origin, // "android:apk-key-hash:<base64SHA256_ofAppSigningCert>", clientId, // "android-origin:<app_package_name>", nonce, // nonce that was used to generate credential request ] AndroidHandoverDataBytes = hashlib.sha256(cbor2.dumps(AndroidHandoverData)).digest()
Transfert vers le navigateur
BrowserHandoverData =[ origin, // Origin URL clientId, // "web-origin:<origin>" nonce, // nonce that was used to generate credential request ] BrowserHandoverDataBytes = hashlib.sha256(cbor2.dumps(BrowserHandoverData)).digest()
En utilisant
SessionTranscript
, la réponse de l'appareil doit être validée conformément à la clause 9 de la norme ISO/IEC 18013-5:2021. Cela inclut plusieurs étapes, par exemple :Vérifiez le certificat de l'émetteur de l'État. Consultez les certificats IACA des émetteurs acceptés.
Valider la signature du MSO (18013-5, section 9.1.2)
Calculer et vérifier les ValueDigests pour les éléments de données (section 9.1.2 de la norme 18013-5)
Valider la signature
deviceSignature
(18013-5, section 9.1.3)
{
"version": "1.0",
"documents": [
{
"docType": "org.iso.18013.5.1.mDL",
"issuerSigned": {
"nameSpaces": {...}, // contains data elements
"issuerAuth": [...] // COSE_Sign1 w/ issuer PK, mso + sig
},
"deviceSigned": {
"nameSpaces": 24(<< {} >>), // empty
"deviceAuth": {
"deviceSignature": [...] // COSE_Sign1 w/ device signature
}
}
}
],
"status": 0
}
Tester votre solution
Pour tester votre solution, compilez et exécutez notre application Android pour titulaire de référence Open Source. Pour compiler et exécuter l'application du titulaire de référence, procédez comme suit :
- Clonez le dépôt des applications de référence.
- Ouvrez le projet dans Android Studio.
- Compilez et exécutez la cible
appholder
sur votre appareil Android ou votre émulateur.
Validation basée sur la preuve à divulgation nulle de connaissance (ZKP)
La preuve à divulgation nulle de connaissance (ZKP, Zero-Knowledge Proof) est une méthode cryptographique qui permet à une personne (le prouveur) de prouver à un vérificateur qu'elle possède une certaine information d'identité ou qu'elle répond à un critère spécifique (par exemple, qu'elle a plus de 18 ans ou qu'elle détient une pièce d'identité valide) sans révéler les données sous-jacentes elles-mêmes. Il s'agit essentiellement d'un moyen de confirmer la véracité d'une déclaration sur l'identité d'une personne tout en gardant les informations sensibles privées.
Les systèmes d'identité numérique qui reposent sur le partage direct des données d'identité demandent souvent aux utilisateurs de partager des informations personnelles excessives, ce qui augmente le risque de violation des données et d'usurpation d'identité. Les ZKP offrent un changement de paradigme, permettant la validation avec une divulgation minimale.
Concepts clés des ZKP dans l'identité numérique :
- Demandeur : personne qui tente de prouver un aspect de son identité.
- Validateur : entité demandant une preuve d'attribut d'identité.
- Preuve : protocole cryptographique qui permet au prouveur de convaincre le vérificateur de la véracité de son affirmation sans révéler les informations secrètes.
Propriétés principales des preuves à divulgation nulle de connaissance :
- Exhaustivité : si l'affirmation est vraie et que le prouveur et le vérificateur sont honnêtes, le vérificateur sera convaincu.
- Solidité : si l'affirmation est fausse, un démonstrateur malhonnête ne peut pas (avec une très forte probabilité) convaincre un vérificateur honnête qu'elle est vraie.
- Connaissance nulle : le validateur n'apprend rien d'autre que la véracité de l'affirmation. Aucune donnée réelle de l'identité du prouveur n'est exposée.
Pour obtenir une preuve Zero Knowledge de Google Wallet, vous devez modifier le format de la requête en mso_mdoc_zk
et ajouter zk_system_type
à votre requête.
...
"dcql_query": {
"credentials": [{
"id": "cred1",
"format": "mso_mdoc_zk",
"meta": {
"doctype_value": "org.iso.18013.5.1.mDL"
"zk_system_type": [
{
"system": "longfellow-libzk-v1",
"circuit_hash": "bd3168ea0a9096b4f7b9b61d1c210dac1b7126a9ec40b8bc770d4d485efce4e9", // This will differ if you need more than 1 attribute.
"num_attributes": 1, // number of attributes (in claims) this has can support
"version": 3
},
{
"system": "longfellow-libzk-v1",
"circuit_hash": "89288b9aa69d2120d211618fcca8345deb4f85d2e710c220cc9c059bbee4c91f", // This will differ if you need more than 1 attribute.
"num_attributes": 1, // number of attributes (in claims) this has can support
"version": 4
}
],
"verifier_message": "challenge"
},
"claims": [{
...
"client_metadata": {
"jwks": {
"keys": [ // sample request encryption key
{
...
Le portefeuille vous renverra une preuve à divulgation nulle de connaissance chiffrée. Vous pouvez valider cette preuve par rapport aux certificats IACA des émetteurs à l'aide de la bibliothèque longfellow-zk de Google.
Pour en savoir plus, vous pouvez contacter l'adresse e-mail de l'assistance.
wallet-identity-rp-support@google.com