🐱

Digital Credentials APIを試してみた

2024/09/15に公開

ChromeでDigital Credentials APIが利用できるようになったとのことなので(まだオリジントライアル中ですが)、少し試してみました。
※2024/09時点

https://developer.chrome.com/blog/digital-credentials-api-origin-trial?hl=ja

  • オリジンを登録する必要があるので、テストページを運用するドメイン(オリジン)が必要になります。
    この記事内ではdc-trial.devとして記載します。
  • 現状利用できるのはAndroidのChromeのみです。
  • 上記リンクを参考にデモアプリ(IC Wallet)をインストールする必要があります。

オリジントライアルの登録

対象の機能はまだオリジントライアル中なので、下記からオリジントライアルの登録をしてトークンを取得します。

https://developer.chrome.com/origintrials/#/trials/active

取得したトークンは、下記のようにメタデータとしてセットして利用します。

<head>
  <meta httpEquiv='origin-trial' content={ORIGIN_TRIAL_TOKEN} />
</head>

Digital Credentials APIの呼び出し

クライアントサイドの実装として、下記のようにnavigator.identity.getを呼び出します。
※PC版Chromeや、Chrome128以前、オリジントライアル未登録だと呼び出すことは出来ません。

const { data } = await navigator.identity.get({
  digital: {
    providers: [
      {
        protocol: 'openid4vp',
        request: {
          client_id: 'dc-trial.dev',
          client_id_scheme: 'web-origin',
          response_type: 'vp_token',
          nonce: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
          presentation_definition: {
            id: 'mDL-request-demo',
            input_descriptors: [
              {
                id: 'org.iso.18013.5.1.mDL',
                format: {
                  mso_mdoc: {
                    alg: ['ES256'],
                  },
                },
                constraints: {
                  limit_disclosure: 'required',
                  fields: [
                    {
                      path: ["$['org.iso.18013.5.1']['family_name']"],
                      intent_to_retain: false,
                    },
                    {
                      path: ["$['org.iso.18013.5.1']['given_name']"],
                      intent_to_retain: false,
                    },
                    {
                      path: ["$['org.iso.18013.5.1']['age_over_21']"],
                      intent_to_retain: false,
                    },
                  ],
                },
              },
            ],
          },
        },
      },
    ],
  },
})

今回はmDLを取得するリクエストになっています。
APIの呼び出しに成功すると、dataとしてvp_tokenを含むJSON文字列が取得できます。

const dataObj = JSON.parse(data)
console.debug('dataObj:', dataObj)
dataObj: {vp_token: 'o2d2ZXJzaW9uYzEuMGlkb2N1bWVudHOBo2dkb2NUeXBl…g6Z5LUsea75r7eccxUHJuoqESEdFZiXZnN0YXR1cwA='}

vp_tokenのデコード

vp_tokenをBase64URLデコード→CBORデコードします。
mDLはCBORらしいです。JSONではないのでご注意ください。

import { decode } from 'cbor-x'

const vpToken = decode(Buffer.from(dataObj.vp_token, 'base64url'))
console.debug('vpToken:', vpToken)
vpToken: {version: '1.0', documents: Array(1), status: 0}

mDLの中身

あとはmDLの中身になりますが、

const doc = vpToken.documents[0]
console.debug('doc:', doc)
doc: {docType: 'org.iso.18013.5.1.mDL', issuerSigned: {…}, deviceSigned: {…}}
import { decode } from 'cbor-x'

const items = doc.issuerSigned.nameSpaces['org.iso.18013.5.1']
console.debug('items:', items)

for (const item of items) {
  console.debug('value:', decode(item.value))
}
value: {digestID: 25, random: Buffer(16), elementIdentifier: 'family_name', elementValue: 'Mustermann'}
value: {digestID: 60, random: Buffer(16), elementIdentifier: 'given_name', elementValue: 'Erika'}
value: {digestID: 13, random: Buffer(16), elementIdentifier: 'age_over_21', elementValue: true}

こんな感じで各要素を参照することができました。
とりあえず、データの参照のみで検証などは省略しています。
今回はAPIを利用してWalletから認証情報(mDL)を取得することが目的なので、mDLの中身(フォーマット)などについては割愛します。

サンプルソース

下記でサンプルソースを公開しています。(Next.jsベースです。

https://github.com/playree/digital-credentials-proto

Discussion