One of the key benefits of digital identity wallets like Google Wallet, the European Union Digital Identity Wallet (‘EUDIW’), Mobile Driver’s Licence (‘mDL’) or similar wallets is that the owner can share certain verifiable information (e.g. prove that the owner is over 18 years of age) from trusted sources.
In this article for developers and other interested parties, we explain how to issue or verify “electronic attestation of attributes” or “verifiable credentials” from such digital identity wallets.
Getting Started with Wallet Identification Development
To get started with Wallet identification development, a good development scope is for a website to receive data from the wallet. If you are starting from scratch, then there are 3 main steps:
1. obtain a wallet, usually a mobile app; however, it can also be a web application;
2. have an attestation of attribute or verifiable credential issued into the wallet [for example, a mDL];
Note: Wallet is initially empty.
3. request the credential [from the wallet], and the steps to verify it are as follows:
- the credential query needs to be compiled and optionally signed and encrypted;
- the credential request must be dispatched; and
- the credentials must be parsed and validated.
In this article, we will focus on the credential request step.
→ At this stage, it is very important to ensure that the credential is issued by a trusted party (e.g. a government agency or accredited entity).
For example, in the USA, the Department of Motor Vehicles (DMV) is issuing mDLs in certain states. As anyone can issue any credentials into a wallet, it is important to be very careful of which parties to trust.
Note: We will focus on dispatching the credential request and parsing and verifying the credentials in later articles.
Requesting Credentials
There are 2 types of flows when requesting credentials, which are the same device and remote device.
1. Same Device - In the same device flow, it is possible to open the app from the browser and share the data directly.
2. Remote Device - In the remote device flow, the credentials are transferred using CTAP protocol. For this flow, it is usual to initiate the transaction by scanning a QR code or over NFC.
If using the same device flow, then the OS will display a prompt to choose the wallet where you want to request the credential from.
For the purposes of this process, we will use an IdentityCredential API. When using IdentityCredential API, the wallet and your website interaction is handled by the browser and OS, which makes the application building very easy.
→ You can see the browser compatibility chart here: https://developer.mozilla.org/en-US/docs/Web/API/IdentityCredential
For testing, we will use the CMWallet app that has source code available here: https://github.com/digitalcredentialsdev/CMWallet. You can build this wallet from source code yourself or you can also install the apk-s included in this Github repository.
When the CMWallet is installed, then for a sanity check you can head over to https://digital-credentials.dev/ and make sure that you can request and share credentials from your CMWallet test app to this website. Google has built a good test site for testing the wallet integrations and we will build the same solution on our own website.
Note: At this moment, DigitalCredentials API is still in development and you need to enable Origin Trials https://developer.chrome.com/docs/web-platform/origin-trials.
You should do this before you start attempting to get credentials on your website or you will get strange errors.
Requesting the Credentials API call itself is quite easy and the flow is described quite well here: https://developers.google.com/wallet/identity/verify/accepting-ids-from-wallet-online#web
credentialResponse = await navigator.credentials.get({
digital: {
providers: [{
protocol: “openid4vp”,
request: request
}]
},
})
The main work here is to compile the DCQL for the request. We will discuss this in detail in later blog posts. Until then, you can use https://digital-credentials.dev/ and create the request using the “Show request” button.
Some wallets might want the query to be signed and possibly even encrypted, so that there is additional security and privacy involved.
If all goes well, then you will have the base64 string that contains the credential that was shared from the wallet.
Validating Credentials
Credentials are in base64-encoded CBOR format. After parsing it, you can get the data, and to be sure that the data is valid, you must verify that the right issuer, whom you trust, has signed it, otherwise, anyone can send you anything. Validation should happen on the server side for additional security.
→ You can find Google Wallet issuer certificates to verify the issuers here: https://developers.google.com/wallet/identity/verify/supported-issuers-iaca-certs#mdl
In a later blog post, we will give details about how to validate the credentials.
For now, we will list the main steps as follows:
1. create the session transcript - this is the dataset that will contain all relevant information for validation;
2. validate the issuer certificate and make sure it is the one that you can trust;
3. verify the MSO signature (18013-5 Section 9.1.2);
4. calculate and check the ValueDigests for Data Elements (18013-5 Section 9.1.2); and
5. verify the deviceSignature signature (18013-5 Section 9.1.3).
You can read more about the credential validation here: https://developers.google.com/wallet/identity/verify/accepting-ids-from-wallet-online#browser-handover
Other Resources and More Reading
Here are some other resources that are helpful to get you going and learn more about identifying people online with different identity wallets like EUDIW, Google Wallet etc.:
One of the API specifications for your website and wallet interaction is OpenID4VP: https://openid.net/specs/openid-4-verifiable-presentations-1_0.html
California mDL verifier test app that allows checking credentials from CA mDL: https://github.com/stateofca/opencred
In addition, Germany has a project that supported 4 EUDIW prototypes and you can find information about them from here: https://www.sprind.org/en/actions/challenges/eudi-wallet-prototypes
For example, the Ubique test app information is here https://funke.ubique.ch/. To go through the full flow then you need to:
- Install the app;
- Issue a credential from https://heidi-showcase.ubique.ch/; and
- Verify credentials from https://heidi-showcase.ubique.ch/verifier
To make it easier to understand EUDIW technical solutions, the EU has compiled an Architecture and Reference Framework ARF, a set of common standards and technical specifications, and a set of common guidelines and best practices. It has been made easy to consume on this page: https://eu-digital-identity-wallet.github.io/eudi-doc-architecture-and-reference-framework/latest/architecture-and-reference-framework-main/
Along with this, we see a lot of source code, technical overview, and sample app on this page: https://github.com/eu-digital-identity-wallet/.github/blob/main/profile/reference-implementation.md#eudi-wallet-reference-implementation
Not Only Google
→ The Apple Wallet for digital identity is also widely used, but is currently available only in apps and not in browsers, and only for a limited set of business cases. More developer information is in here: https://developer.apple.com/wallet/get-started-with-verify-with-wallet/
→ We should also mention Samsung Wallet verification, where developer docs are found on this page: https://developer.samsung.com/wallet/api_new/verifywith/overview.html
If you have additional questions or need any development help regarding the wallet, feel free to reach out - we're here to help!