Encrypted Object Formats

  • The Identity Credential library on Android devices securely manages credentials, providing security features for issuers to ensure secure integration.

  • A signed nonce, or "challenge," is used when retrieving the device identity certificate to confirm its recency and prevent replay attacks.

  • Access control profiles allow issuers to define how data within Identity Credential is protected, including specifying user authentication requirements and access limitations.

  • Proof of provisioning verifies that a credential was successfully stored, and issuers should not issue Mobile Security Objects (MSOs) until receiving and verifying it.

  • Mobile Security Objects (MSOs) are used to ensure the integrity and authenticity of mDL data, containing digest values, a device key, validity information, and an issuing authority signature.

Identity Credential

Android devices use the Identity Credential library to securely manage credentials on the device. The Identity Credential library offers a number of security features that should be used by the issuer to ensure their integration with Google is as secure as possible.

Signed Nonce

The Identity Credential library takes a "challenge" (referred to in this API as the nonce) when retrieving the device identity certificate, sent to the issuer in the RegisterDeviceRequest. This nonce is signed and embedded in the attestation extension of the device identity certificate. This allows the issuer to have confidence in the recency of the certificate and attestation, and that it isn't being replayed by a server in the middle of the communications.

Access Control Profiles

Access control profiles are a way for the issuer to specify precisely how they want the data being stored within Identity Credential to be protected. The issuer is able to specify if user authentication is required to access the data element, and how long the user has to perform authentication. Future (not currently supported) use cases of this feature include limiting which readers are able to access the data element. Details on how to format access control profiles can be found in the Credential object format.

Proof of Provisioning

The proof of provisioning object is a way for issuers to know that the credential was successfully stored within Identity Credential. An issuer should not issue MSOs for a credential until they receive and verify the proof of provisioning. This object is documented more in the Identity Credential documentation.

Object Formats

Each of these objects are end-to-end encrypted between the device and the issuer. As a result, Google's servers do not have the capability to normalize these objects, and some of these objects may be in different formats than the rest of the API objects. For example, the Credential is formatted in CBOR rather than JSON, as that is what is expected at the Android level.

Credential

The credential contains the data elements, and how they should be accessed. It contains two primary objects, provisionedData and accessControlProfiles. The provisionedData contains all of the namespaces relevant to whatever the credential type is. For example, for mobile driver's license, this would be org.iso.18013.5.1 and org.aamva.18013.5.1. The data entries and values inside of the namespaces specify the relevant access control profiles. This is done as a list of ids, where the id corresponds to an access control profile in the accessControlProfiles list. In the example below, the [0] in each data entry refers to the access control profile with id 0, not index 0.

Below is an example of an unencoded CBOR map data item.

{
  "provisionedData": {
      "org.iso.18013.5.1": [
          {
              "name": "family_name",
              "value": "Smith",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "given_name",
              "value": "Stewart",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "birth_date",
              "value": {
                  "tag": 1004,
                  "value": "1965-09-01"
              },
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "issue_date",
              "value": {
                  "tag": 1004,
                  "value": "2022-08-01"
              },
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "expiry_date",
              "value": {
                  "tag": 1004,
                  "value": "2027-08-01"
              },
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "issuing_authority",
              "value": "IA",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "issuing_country",
              "value": "US",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "document_number",
              "value": "D04320785",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "portrait",
              "value": {
                  "type": "Buffer",
                  "data": [
                      167,
                      30,
                      148,
                      218,
                      204,
                      75,
                      112,
                      162,
                      138,
                      40,
                      52,
                      63,
                      255
                  ]
              },
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "un_distinguishing_sign",
              "value": "USA",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "driving_privileges",
              "value": [
                  {
                      "expiry_date": {
                          "tag": 1004,
                          "value": "2027-08-01"
                      },
                      "issue_date": {
                          "tag": 1004,
                          "value": "2022-08-01"
                      },
                      "vehicle_category_code": "B"
                  }
              ],
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "sex",
              "value": 1,
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "height",
              "value": 170,
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "weight",
              "value": 79,
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "eye_colour",
              "value": "Blue",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "hair_colour",
              "value": "Gray",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "age_in_years",
              "value": 57,
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "age_over_18",
              "value": true,
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "age_over_21",
              "value": true,
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "resident_address",
              "value": "1600 Amphitheatre Pkwy ",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "issuing_jurisdiction",
              "value": "US-CA",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "resident_city",
              "value": "Mountain View",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "resident_state",
              "value": "CA",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "resident_postal_code",
              "value": "94043",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "resident_country",
              "value": "US",
              "accessControlProfiles": [
                  1
              ]
          }
      ],
      "org.iso.18013.5.1.aamva": [
          {
              "name": "DHS_compliance",
              "value": "F",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "domestic_driving_privileges",
              "value": [
                  {
                      "domestic_vehicle_class": {
                          "domestic_vehicle_class_code": "D",
                          "domestic_vehicle_class_description": "Operator",
                          "expiry_date": {
                              "tag": 1004,
                              "value": "2027-08-01"
                          },
                          "issue_date": {
                              "tag": 1004,
                              "value": "2022-08-01"
                          }
                      },
                      "domestic_vehicle_restrictions": [
                          {
                              "domestic_vehicle_restriction_code": "B",
                              "domestic_vehicle_restriction_description": "Corrective lenses (also automated - vision screening)"
                          }
                      ]
                  }
              ],
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "aamva_version",
              "value": "1",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "family_name_truncation",
              "value": "N",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "given_name_truncation",
              "value": "N",
              "accessControlProfiles": [
                  1
              ]
          },
          {
              "name": "organ_donor",
              "value": true,
              "accessControlProfiles": [
                  1
              ]
          }
      ]
  },
  "accessControlProfiles": [
      {
          "id": 1,
          "userAuthenticationRequired": true,
          "timeoutMillis": 10000
      }
  ]
}

This object should then be encoded in the CBOR format, encrypted, and then base64 encoded. If in the test environment, and the data is not being encrypted, it should be encoded in the CBOR format, and then base64 encoded.

Note that the above example is an unencoded CBOR map, not JSON. If a JSON string is encoded into CBOR, it will not be correctly parsed by the Android device.

Mobile Security Objects

ISO/IEC 18013-5 defines a Mobile Security Object (MSO) to ensure that the mDL data is not tampered with and that it was issued by a trusted authority.

MSO contains the following:

  • Digest values: These are unique values that are generated for each data element in the mDL Credential. They are used to verify that the data has not been changed since the MSO was signed.
  • Device key: This is a unique key that is generated for each mobile device that stores the Credential. It is used to bind the MSO to the device and to prevent it from being used on other devices.
  • Validity information: This includes the start and end dates for which the MSO is valid.
  • IA signature: This is a digital signature that is created by the Issuing Authority (IA) using its private key. It is used to verify that the MSO was issued by a trusted authority.

MSO has the following CCDL structure:

   MobileSecurityObjectBytes = #6.24(bstr .cbor MobileSecurityObject)
   MobileSecurityObject = {
      "digestAlgorithm" : tstr,        ; Message digest algorithm used
      "valueDigests" : ValueDigests,   ; Array of digests of all data elements
      "deviceKeyInfo" : DeviceKeyInfo,
      "docType" : tstr,                ; DocType as used in Documents
      "validityInfo" : ValidityInfo
   }
   DeviceKeyInfo = {
      "deviceKey" : DeviceKey
      ? "keyAuthorizations" : KeyAuthorizations,
      ? "keyInfo" : KeyInfo
   }
   DeviceKey = COSE_Key                ; Device key in COSE_Key as defined in RFC 8152
   KeyAuthorizations = {
      ? "nameSpaces" : AuthorizedNameSpaces
      ? "dataElements" : AuthorizedDataElements
   }
   AuthorizedNameSpaces = [+ NameSpace]
   AuthorizedDataElements = {+ NameSpace => DataElementsArray}
   DataElementsArray = [+ DataElementIdentifier]
   KeyInfo = { * int => any}           ; Positive integers are RFU, negative integers may be used for proprietary use
   ValueDigests = {
      "nameSpaces" : NameSpacesDigests
   }
   NameSpacesDigests = {
      + NameSpace => DigestIDs
   }
   DigestIDs = {
      + DigestID => Digest
   }
   ValidityInfo = {
      "signed" : tdate,
      "validFrom" : tdate,
      "validUntil" : tdate,
      ? "expectedUpdate" : tdate
   }
   NameSpace = tstr                    ; NameSpace as used in IssuerSigned
   DigestID = uint                     ; DigestID as used in IssuerSig

Static Auth Data

The Static Auth Data, which comprises both the digestIdMapping and the issuerAuth, should be constructed by the issuer.

The digestIdMapping for a specific namespace consists of an array of IssuerSignedItem instances, each with a null value for the elementValue property. Additionally, the issuerAuth is generated by signing the MobileSecurityObjectBytes using COSE_Sign1.

   StaticAuthDataBytes = (bstr .cbor StaticAuthData)
   StaticAuthData = {
      "digestIdMapping" : DigestIdMapping,
      "issuerAuth" : IssuerAuth
   }
   DigestIdMapping = {
      NameSpace => [ + IssuerSignedItemBytes ]
   }
   ; Defined in ISO 18013-5
   ;
   NameSpace = String
   DataElementIdentifier = String
   DigestID = uint
   IssuerAuth = COSE_Sign1 ; The payload is MobileSecurityObjectBytes
   IssuerSignedItemBytes = #6.24(bstr .cbor IssuerSignedItem)
   IssuerSignedItem = {
      "digestID" : uint,                           ; Digest ID for issuer data auth
      "random" : bstr,                             ; Random value for issuer data auth
      "elementIdentifier" : DataElementIdentifier, ; Data element identifier
      "elementValue" : DataElementValue            ; Data element value
   }

Upon invocation of the /provisionMobileSecurityObjects endpoint, the StaticAuthDataBytes is encrypted using HPKE, and transmitted as part of the response.

Here's a code sample for constructing MSOs and Static Auth Data.