NDEFレコードをICカードから読み出して解析してみた

NDEF(Near field communication Data Exchange Format)について、いろいろな資料を読んでみましたが、いまいち、分からないんですよね。

なんで、具体的なデータで説明してくれないんだろう。

そこで、某ツールでICカードに書き込んだNDEFレコードを読み出して解析してみました。

NDEFレコードはTLVのVに入れ子構造になって格納される

NFC(Near Field Communication)でダイナミックメモリを用いる場合、しばしばTLV(Tag, Length, Value)ブロックが使われます。すなわち、Tag部でブロックの用途を示し、Length部でデータのサイズを表し、Value部にデータを格納します。

NDEFレコードの構造

NDEFレコードの構造

NDEFレコードは、NFC Forumが策定したタグ表現のための共通フォーマットです。このNDEFレコードは、TLVのVの部分に格納されます。

また、NDEFレコードにはいくつかのタイプがあります。例えば、スマートポスタレコードは、テキストレコードやURIレコードを包含することができます。

スマートポスタレコードの書き込み例

スマートポスタレコードをType 2のタグとして、MIFARE Ultralight Cのカードに書き込んだ例を示します。バイナリデータの右側にはアスキーデータも示しました。

00h: 04-53-86-59 _S?Y
01h: DA-1B-5C-80 ?_\?
02h: 1D-48-00-00 _H??
03h: E1-10-12-00 ?__?
04h: 01-03-A0-0C __?_
05h: 34-03-3E-D1 4_>?
06h: 02-39-53-70 _9Sp
07h: 91-01-15-54 ?__T
08h: 02-6A-61-E3 _ja?
09h: 81-95-E3-81 ????
0Ah: 97-E3-81-82 ????
0Bh: E3-81-9F-E3 ????
0Ch: 81-A3-E3-81 ????
0Dh: A6-11-01-15 ?___
0Eh: 55-04-6D-69 U_mi
0Fh: 73-63-65-6C scel
10h: 6C-61-6E-65 lane
11h: 6F-75-73-2E ous.
12h: 74-6F-6B-79 toky
13h: 6F-2F-51-03 o/Q_
14h: 01-61-63-74 _act
15h: 00-FE-00-00 ????
16h: 00-00-00-00 ????

27h: 00-00-00-00 ????
28h: 00-00-00-BD ????
29h: 04-00-00-FF _???
2Ah: 00-05-00-00 ?_??
2Bh: 00-00-00-00 ????

このうち、最初から05hページの0hバイト(34h)迄と15hページの2hバイト(00h)から最後までの内容は、こちらの記事で解説しているので、本記事では省略します。

新品の無線ICカードを読んでみたら、NDEFフォーマットされたMIFARE Ultralight Cだった
秋葉原で数年前に新品として買ってきた非接触型ICカード(PICC: Proximity IC Card)を読んでみました。PICCとは、Suicaや免許のような無線通信できるICカードの総称です。 カードは、MIFARE Ultralig...

TLVブロック

NDEFレコードは05hページの1hバイトから始まります。すなわち、03-3E-…です。
03hはTagで、「NDEF Message TLV」を示します。
3EhはLengthで、データが3Ehすなわち、62バイトであることを示しています。
その次のD1hのバイトから62バイトを数えると、15hページの0hバイトの00hまでとなります。その次のFEhは、Tagで、「Terminate TLV」を示します。つまり、NDEFメッセージは、この1つのVの中に全て含まれています。

スマートポスタレコード

NDEF Message TLVのVである05hページの3hバイトからスマートポスタレコードが始まります。すなわち、D1-02-39-53-70-91–…の部分です。

NDEFレコードの構成

NDEFレコードの構成[1]

NDEFレコードの先頭ビットは、上図に示すように、フラグ類から構成されます。略語の意味は次の通りです。

略語 意 味
MB  Message Begin(メッセージ開始)
ME  Message End(メッセージ終了)
CF  Chunk Flag(分割されたPAYLOADに続きがある)
SR  Short Record(ペイロード長が1バイト以下)
IL  ID Length(IDの長さフィールドが存在する)
TNF  Type Name Format(レコードタイプ)

このスマートポスタレコードの先頭バイトは、D1hであり、これを2進法に直すと、「1101 0001」です。よって、MB、ME、SRフラグが立っていて、TNFは01hということになります。この意味は、メッセージの開始であって終わりということなので、NDEFレコードは1つだけです。また、SRフラグが立っているので、ペイロードは1バイトであらわされる数値以下、つまりFFh(255)バイト以下です。

次にTNFです。TNFは3ビットで、以下の表に示すように、レコードタイプを示します。
ここでは、001b = 01hなので、Well-knownです。

TNFの値 レコードタイプ 意 味
0h Empty
1h Well-known タイプにRecord Type Definition形式を用いる
2h MIME Media MIMEタイプ
3h Absolute URI 絶対URI
4h External RTD外部
5h Unknown ペイロードが不明
6h Unchanged チャンクの最初ではない

続く02hは、Typeの長さが2バイトであることを意味します。
39hは、ペイロードの長さが57バイトであることを意味します。
53-70はTypeであり、アスキーコードとして変換すると、「Sp」です。つまり、このNDEFはスマートポスタレコードです。
その次の91hからペイロードが始まります。ここから57バイトを数えると、15hページの0hバイトまでということになります。その次はNDEFの終わりを示すFEhですから、TLVのVの部分はスマートポスタレコードが1つだけ入っていることが分かります。

07hページの0hバイトからテキストレコードが始まります。すなわち、91-01-15-54-02-6A-61-E3-…の部分です。
91hは、NDEFの先頭ビットですから、フラグ類で構成されています。2進法に直すと「1001 0001」です。すなわち、MB、SRフラグが立っていて、TNFは01hということになります。よって、本NDEFはスマートポスタの最初のレコードであって、(MEが立っていないことから)後にまだ続くレコードがあることが分かります。また、SRフラグが立っているので、ペイロードは255バイト以下であることも分かります。
さらに、TNFは01hなので、このNDEFもWell-knownタイプです。
続く01hは、Typeの長さが1バイトであることを示します。
さらに、15hは、ペイロードの長さが21バイトであることを示します。
54hは1バイト長のTypeであり、アスキーコードと見なすと「T」です。よって、このNDEFがテキストレコードであることが分かります。
ペイロードの0バイト目、すなわち02hは、文字に関するフラグ類で構成されています。2進法に直すと「0000 0010」です。ここで、MSB(最上位ビット)をb7、以下LSB(最下位ビット)をb0と呼ぶことにします。ここで、b7は、0ならUTF-8、1ならUTF-16を表します。よって、このテキストはUTF-8でエンコードされていることが分かります。
さらに、b5~b0は、言語コードの長さを示します。000010bは2バイトを意味するので、続く6A-61の2バイトが言語コードを示しています。アスキーコードを変換すると、「ja」です。つまり日本語です。
UTF-8では日本語の1文字は3バイトで表されます。ペイロードの21バイト中、3バイトを既に使っているので、残りの18バイトを3文字ずつ区切ってみます。すると、「E3-81-95」「E3-81-97」「E3-81-82」「E3-81-9F」「E3-81-A3」「E3-81-A6」となり、これをデコードすると「さしあたって」の6文字となります。本ブログのタイトルでした。

次は、URIレコードです。0Dhページの1hバイトから始まる11-01-15-55-04-6D-…の部分です。
11hは例によって、フラグ類で構成されています。2進数に直すと「0001 0001」です。よって、SRフラグのみが立っていて、TNFは1hです。すなわち、一連の途中のNDEFレコードであり、ペイロードは255バイト以下です。また、Well-knownタイプであることも分かります。
続く01hから、Typeの長さが1バイトであることがわかります。また、ペイロード長は15h、すなわち、21バイトです。
タイプは55hの1バイトで示され、文字に直すと「U」です。これは、URIレコードであることを示します。
04hからペイロードが始まりますが、その1バイト目は、URI識別コードです。文献[2]の表23-3から抜粋すれば、

コード 接頭辞
0x01 http://www.
0x02 https://www.
0x03 http://
0x04 https://

となるので、「https://」であることがわかります。そこから、6D-69-73-63-65-6C-6C-61-6E-65-6F-75-73-2E-74-6F-6B-79-6F-2Fと続く20バイトを文字に直して接頭辞につなげると、「https://miscellaneous.tokyo/」となります。本ブログのURIでした。

最後に、アクションレコードがあります。
51-03-01-61-63-74-00という短いレコードです。
例によって、51hを2進数に直すと、「0101 0001」ですので、MEとSRフラグが立っています。また、TNFは1hです。これらのことから、最後のレコードであること、ペイロードが255バイト以下、Well-knownであることが分かります。
TYPEの長さ及びIDの長さはそれぞれ、03hバイト、01hバイトです。TYPEを示す61-63-74の3バイトを文字に直すと、「act」なので、アクションレコードであることが分かります。そのアクションは、00hなので、実行することが推奨されています。

最後に終了コードであるFEhが来て、NDEFは終了です。

まとめ

NDEFのバイナリデータをカードから読み出して、解析しました。ここで示したタグを適当なリーダで読めば、本ブログが開くはずです。残念ながら、僕の手元にリーダが無いので、試すことはできませんでした。


[1] https://learn.adafruit.com/adafruit-pn532-rfid-nfc/ndef
[2] 株式会社ブリリアントサービス:NFC HACKSプロが教えるテクニック&ツール、オライリー・ジャパン、pp.128-134、2013、ISBN978-4-87311-624-2

コメント

タイトルとURLをコピーしました