1. はじめに
券面記載事項であろうと、それ以外であろうと、その利用方法には(1)デジタルのままデータとして送信して利用する方法と(2)画面や紙の上に表示して使う方法の2種類がありうる。前者の場合は署名付きの構造化データ、たとえばJWS証明付きのJSONなどで提供すればよいのであり、APIを通じた提供方法としてごく標準的なものが適用可能である。しかし、後者の場合、単純に値を表示・印刷するのでは、その値の否改ざん性などは一般に担保できず、安全な環境で特殊な紙に印刷することによって担保するというのが一般的であった。しかし、この方法では、幅広い利用は難しい。
そこで、本文書では、QRコードを活用することによって、画面や紙を経由して相手にデータを引き渡しても、その否改ざん性を担保可能な方式を記す。
2. 語彙と定義
本文書ではRFC7515およびRFC7519に定義される語彙を採用する。
3. 省略語
- JSON JavaScript Object Notation
- JWS JSON Web Signature
- JWT JSON Web Token
4. 方式
4.1 署名方式
QRコードに署名を収めるためには、比較的小さな署名を生成するアルゴリズムを選択しなければならない。署名方式は、以下のとおりとする。
- 署名フォーマット: JWS[RFC7615]の分離署名(Detached Signature)
- アルゴリズム(alg):ES256
- ペイロードタイプ(cty): URL or CJWT
4.2 JWSヘッダ
JWSヘッダは、以下のものを含む
- 必須ヘッダ:alg, cty
- 推奨ヘッダ:jku, kid
アウト・オブ・バウンズでJWKがわかっていない限り、jkuをヘッダに含めなければならない。どのキーを使ったかがアウト・オブ・バウンズで明確で無い限り、kidをJWSヘッダに含めなければならない。
4.3 ペイロード
ペイロードはデータベースに収めたり、他の情報と組み合わせて使ったりなどが考えられるため、JSONなどに構造化された形式であることが求められる。だが、そのようなペイロードは、多くの場合、QRコードにそのまま収めるのには大きすぎる。そのため、対象となるものは何らかの形で小さく変換する必要がある。本文書では、URL参照方式、辞書圧縮方式の2つの方法を提案する。
4.3.1 URL参照方式
URL参照方式では、データ自体はあるURLが指し示すネットワーク上の場所に保管することとする。URLは、データ取得時の機密性をまもるため、HTTPS URLでなければならない。URLには、対象データの改ざんをチェックできるように、データ自体のSHA256 Hash値をつけなければならない。
例:
https://example.com/sub/hikari.go/4info#base64encoded_sha256_hash_of_the_payload
URL参照方式のほうが辞書圧縮方式より処理が簡単であり、大きなペイロードを取り扱えるメリットが有る。一方では、オフラインで完結しないという欠点も持っている。
4.3.2 辞書圧縮方式
ペイロードは一般的に比較的小さく、繰り返しが少ないので、汎用的な圧縮はあまり効かない。そこで、変数の順序を規定し、変数名を省略するとともに、値についてはアプリケーション用の圧縮用辞書を用意し、これをつかって圧縮する。
変数の順序を規定したファイルはissuerの.well-known/jwt-orders.json から取得できなければならない。
jwt-orders.jsonは、以下の2つのメンバーを持つJSONファイルである。
- delim
- 必須。圧縮JSON内で、各メンバーの値を区切るために使われる文字のJSON String表現。
- mem
- 必須。圧縮JSON生成時のメンバー値の並び順を規定した順序付JSON配列。必ずissuerを含まなければならない。Nest値については、Flat表記を用いなければならない。
変数の値の圧縮に使用する辞書は、issuerの.well-known/compress-dict.json から取得できなければならない。
compress-dict.json は、各メンバー値の置き換えに利用する値を表したJSONファイルである。トップレベルメンバーは、変数名であり、その値はJSONオブジェクトで、メンバー名に置き換えられる語、メンバー値に置き換後の語を持つ。トップレベルメンバーには特殊値「_default」がある。このメンバーの値には、他のトップレベルメンバーで規定されていない置き換え辞書が収められる。
圧縮は、以下のプロセスで行われる。
- 対象となるJSONをFlat化する。
- Flat化したJSONをjwt-order.jsonのmemで規定された順に並び替える。
- それぞれのメンバー名を使い、対象となる置き換え辞書をcompress-dict.json から選択し、メンバー値を対応する値で置き換える。
- 置き換え後の値を、順序を保存したまま、jwt-orders.jsonのdelimメンバーの値で連結し、一つのUTF8文字列を生成する。
オフライン環境に強いのが辞書圧縮方式のメリットである。しかし、処理は、URL方式より複雑であり、取り扱えるペイロードのサイズも小さいというデメリットが有る。
4.4 署名の生成
署名の生成はJWS[RFC7615]の規定に従わなければならない。
対象となるペイロードは、4.2で生成したものである。
4.5 QRコード化
署名付きデータは、JWS分離署名である。ペイロードと分離署名それぞれでQRコードで表現する。2つのQRコードは、縦ないしは横に並べる。縦並びの場合は、上がペイロード、横並びの場合は左がペイロードである。
4.6 署名検証
署名検証にあたっては、JWSの署名検証プロセスに従う。
4.7 アプリケーション判断
そのJWSが有効であるかは、署名が正しいだけでなく、ペイロードの内容がアプリケーションの必要とする要件を満たしているかどうかを確かめなければならない。たとえば、いわゆる属性証明のような場合、ペイロードに含まれる「iss」の値が、JWSヘッダの「jku」の値の前方部分一致することが求められるなどが考えられる。これは、アプリケーションごとに定めなければならない。
5. 例
Payload
{“name”:”郷ひかり”,”gender”:”F”,”birth_date”:”1964-10-01″,”address”:{“region”:”東京都”,”locality”:”千代田区”,”street_address”:”大手町1丁目1番地123大手町レジデンス1504号室”},”email”:”hikari.go@example.com”,”email_verified”:true,”jti”:”EFGX9F”,”sub”:”1234567890128″,”iat”:1494669600,”exp”:1546300799,”iss”:”https://example.com”}
JWS Header
{“alg”:”ES256″,”kid”:”C03MT”, “jku”:”https://example.com/jwks”,”cty”:”JWT”}
Compressed Payload
郷ひかり:F:boz3d:d:2t:大手町1丁目1番地123大手町レジデンス1504号室:hikari.go@example.com:1:EFGX9F:1234567890128:pkmlbz:opvyg0:https://example.com
Signature
eyJhbGciOiJFUzI1NiIsImtpZCI6IkMwM01UIn0..iXNAHvr55iw4LSnaGGZI7nq7hM4mOON0ccj7PnW5He9LuqAX5MSaNpeIFQM4HnkOkUPVunmQz6Yi3zLIfisfkQ
Payload URL
Signature
6. セキュリティ配慮
7. プライバシー配慮
8. IANA配慮
9. Acknowledgement
Normative References
Informative References