C#でNFC(Felica/Mifare)の読み取り – 実践編 その4 – Mifare Ultra Light(NTAG21x)への読み書き前に仕様をよく読む

NFC
スポンサーリンク
スポンサーリンク

Mifare Ultra Lightとは?

自分のわかっている範囲でまとめておくと

  • NXP NTAG 213/215/216
  • ネット通販大手さんでも市販されているNFCのタグです。安価。
  • 比較的管理が簡単で、API等もめんどくさくなく気軽に扱えるNFCタグ
  • シール等で貼り付けて WifiのAPの設定を簡単にしたり、お店等でURLを入力せずに簡単に案内を表示できたりします。
  • NFC Fourm Type2 Tag, ISO/IEC14443 TypeA
  • ぞぞスーツ等でも使われてるらしい。
  • 最近はNFCのおもちゃとかが出てる。その中にも使われている様子。これとかも。
  • コラントッテとか、ピップエレキバンの磁気のパッチじゃない(嫁にそれを通販したのかと疑われた。)

のようになります。まだまだこれから調べいきます。

必要なもの

  • 仕様書 NTAG 213/215/216(ダウンロードしておくと便利)(編集時点 265332)
  • いつものPasoriとPCSCはまた次の記事にて。

じっくり仕様書を読む

まずはゴリゴリ仕様書を見ていきたいと思います。次のような図がありますので、これに沿って、読み込んでいきます。以下、色のついた部分は意訳。と仕様書の引用等です。

“8.5 Memory organization” – Fig5.

UID/Serial number (8.5.1)

uniqueな7-byteのシリアル番号(UID)と2つのチェックバイトからなり、アドレスは、ページ 0h,1hと2hの初めの1バイトです。アドレス02hの2バイトめは、 internalデータとして、予約されいます。これらのバイトは生産時のテストでプログラムされ、書き込み保護されています。from 8.5.1 UID/Serial number

先ほどの図ではこの部分。

またこのうちの ページ 0h, 1h, 2hを横に取り出して説明したのが、Fig 8.です。

チェックバイトの計算の詳細はよくわからないけれど、参考にしたい場合は仕様書に書かれています。とりあえず、UIDは取得できたらよいので、特にこれ以上は深掘りしません。たぶん前にやったPCSCでコーディングすれば取得できると考えています。

C#でNFC(Felica/Mifare)の読み取り - 実践編 その1 - ATR, IDm/UID, カードタイプの取得
今回の到達点 PCSC-SharpとPSCS.ISO7816を使用して、以下のことができるようになる。 Felica(Suica/ICOCA)のIDmを読み込めるようになる。 Mifare?(T-money)のUIDを読み込...

Statick lock bytes (8.5.2)

静的ロック機能。この領域を設定することで、書き込みロックを行う領域を指定できます。ブロックでの書き込みロック領域(BL), ページ単位での書き込みロック領域(Lx)があります。詳細にみていきましょう。メモリ領域では、この部分です(黒)。

ページ02hの2,3バイト目は、プログラム可能で、読み込みのみ(read-only)ロックができる機構を表しています。
ページ03h~0Fhまでを個別にロックできます。さらなる書き込みを避けるために、対応するロックビット(Lx)を1にセットします。

ブロックロックビット(BL)について

この部分への操作は要注意です。一度設定すると元に戻せません。データの変更対策に用いる機能です。デフォルトは 00 00h です。

lock byte 0 の一番下の3つのビットが,ブロックロックビット(BL ,block-locking bits)です。
Bit2がページ 0Ah~0Fhに相当し(BL15-10).
Bit1がページ 04h~09hに相当し(BL15-10).
Bit0がページ 03h(CC)に相当し(BL CC).
このブロックビットが一度でも論理 “1”にセットされると、対応するメモリ領域のロック設定が凍結されます。
例えば、 “BL15-10″のビットが論理 “1”(対応するビット位置を1)にセットすると、そのL15からL10(lock byte1のbit7-bit2)がもはや変更できません。

(CC はCapability Containerを表す。)

ブロックロックビットは、ページ02hへの “WRITE” or “COMPATIBLITY_WRITE” コマンドによりセットされます。
2,3バイトへの “WRITE” or “COMPATIBLITY_WRITE” コマンドは、とその内容はbit-wiseのOR演算されてます。
結果、ロックバイトの内容が更新されます。この操作はもとに戻せません。(論理 “1”にすると、論理 “0”には戻せません。)

Dynamic lock bytes (8.5.3)

少し先へ飛んで、Dynamic lock bytesの説明へ。図の中の黒の部分

Statick lock bytesと異なり、

ページ10h (16)のアドレスから始まるロックにはDynamic lock bytesを用います。NTAG 213では “28h”, NTAG215では “82h”, NTAG216では “E2h”に位置しています。それぞれカーバーする領域として、NTAG213では 96bytes, NTAG215では 456bytes, NTAG216では 821bytesとなり、それぞれのTAGによって、粒度が異なります。

Fig10(NTAG213), Fig11(NTAG215), Fig12(NTAG216)参照。下はFig10参照。

Dynamic lock bytes内のRFUIは論理 ”0” に設定されています。

Capability Container (CC Bytes) (8.5.4)

CCについてはここが参考になります。ありがたい。

ページ3 にある、Capability Container (CC bytes)はNFC Fourm Type 2 Tag仕様に従って、ICの生産するときにプログラムされます。WRITE” or “COMPATIBLITY_WRITE” コマンドでbit-wiseに変更されます。

書き込むと結果、ロックバイトの内容が更新されます。この操作はもとに戻せません。(論理 “1”にすると、論理 “0”には戻せません。)

との内容なので、特に触る必要もない感じがしてきました。8.5.6の出荷設定がわかっていれば、その通りになっているはずで、特にこの領域は気にせずに置きます。あるとすれば、213,215,216で特定の値になっているので、分類には用いれるかもしれません。

Data pages (8.5.5)

ユーザがRead / Write 可能なエリアです。

NTAG213: 04h – 27h
NTAG215: 04h – 81h
NTAG216: 04h – E1h

ユーザメモリエリアへのアクセスは、パスワード認証を使って、制限が可能。(Chapter 8.8参照)

Memory content at delivery (8.5.6) [出荷時のメモリ内容]

03h(CC)と04h,05hは出荷時の初期データが以下の用に決まっていますが、05h以降は出荷時のデータが決まっていません。これらの値を見て、出荷状態かどうかを判断することが可能です。

Configuration pages (8.5.7)[設定ページ]

UID ASCII mirror, NFC counter mirrorを使用するかの設定、パスワード、パスワードでの書き込みロックを使用するかの設定等を行う領域です。

これの設定の部分を詳細にみると、以下のようになります。結構な機能がこのページで設定することで有効・無効にすることが可能です。

MIRROR PAGE, AUTH0, PWD, PACKについて

MIRROR byte内のビット設定について

ACCESS byte内のビット設定について

NFC counter function (8.6)

カウント値でTAGの読み取り回数を出すことで、どの程度使用したか、壊れやすいのはどの程度かなどがわかるかとも考えています。また自分たちのシステム以外で読み取りを行おうとしたのかなど、悪意あるユーザの行為を防止するなどにも使用できるかと思います。

NTAG21xの機能として、NFC counter 機能があります。この機能は24bitのカウント値を自動的に行います。RFの電磁場により活性化されて、初めの有効になった READコマンドか、 FAST-READコマンドがカウントのトリガーになります。

NFC counter が最大の 0xFF FF FF (FF FF FF hex)の値に到達すると、カウント値はそれ以上変化しません。NFC counter 機能はNFC_CNT_EN bit (Section 8.5.7参照)で有効・無効になります。実際のカウント値は、READ_CNT コマンドか、NFC counter mirror 機能により、読み取ることが可能です。

カウント値をパスワードで保護して、どのようなアプリケーションで活用するのかは、少し思いつかないのですが、いろいろな機能があります。

NFC counter 機能はパスワード認証で保護することも可能です。NFC counter のパスワード保護は、NFC_CNT_PWD_PROT bit (Section 8.5.7参照)で、有効化無効化が可能です。

他にも有用な使用方法を思いついたら、メモしていきたいと思います。

思いついたのでメモ:
例えばあるサイト・サービス等の使用上限回数として、タグの読み取り回数などを設定するのもありかもしれません。読み取りミスは+αで余裕を見ておいてもよいかもしれません。例えば10回使用する権利を1000円程度で売っておき、読み取りカウントミス分を+2回程度にしておけば、タグの元はとれるかもしれません。ただの思い付きです。

ASCII mirror function (8.7)

NTAG21x の機能に、ASCII mirrorがあります。この機能はNTAG21xに仮想的なミラーとして、次のような値をアスキーコードとしてICの物理メモリの中に埋め込んで使用することができます。

  • 7 byte UID (Section 8.7.1 参照)
  • 3 byte NFC counter value (Section 8.7.2 参照)
  • 7 byte UID and 3 byte NFC counter value の両方と a separation byte(Section 8.7.3 参照)

初めはこの機能何のことを言っているのかわからなかったのですが、想像してみるとかなりよい機能だと思います。

というのも、user mermoryの部分にある種の鏡を設定して、読み取りデータの中にUIDとかcounter値をASCIIコードで埋め込むことができるということです。

つまり、「counter値」・「UID」・「memoryのデータ」をすべて別々に読み取って、アプリケーション側で結合させなくとも、「memoryのデータ」を読み取りさえすれば、その中にUIDとcounter値をASCIIコードにして埋め込んで使用できるので、読み取りの動作を素早く・1回で読み取れる機能なのです。鏡のように、データをメモリの中に投影するようなイメージです。

ASCII mirror機能に要求される予約物理メモリは、表12に示してあります。ASCII mirrorがuser memoryエリアを超えると、そのデータはミラーできません。

正しく設定しないと、メモリの中にデータを設定できません。正しい値をメモリの中に設定してください。

MIRROR_PAGEはミラーの開始位置(ページ)とMIRROR_BYTEはページ内のオフセット値を設定します。

UID and/or NFC counterのミラリングがメモリのどこで開始されるべきかという位置は、MIRROR_PAGEと MIRROR_BYTEの値によって定義されるます。

MIRROR_PAGEはASCIIミラーがどこから開始されるかという値を定義し、MIRROR_BYTEはページ内のどの位置で開始するかという値を定義します。

ASCII mirror機能は03h以上で有効になります。

MIRROR_CONF bitでUIDだけ、NFC counterだけ、その両方を設定できます。両方を選んだ場合は、 “x”(78h ASCII)で自動的に分割されます。

UID ASCII mirror function (8.7.1)

結構がっつり見てきたので、じれてきました。ここはもう例題から見たほうが早い。

ミラー機能としては、以下のようになりますよという例です。
ここでUIDは、 “04-E1-41-12-4C-28-80h”であるとします。

  1. ミラー機能を正しく使うお作法にのっとり、Tagにデータを書き込み。以下の様に設定
  2. 物理メモリの値  ”http://www.nxp.com/index.html?m=00000000000000”
  3. カードリーダで読み取る。次のような値が取得できる。
  4. 仮想メモリ内の値 ”http://www.nxp.com/index.html?m=04E141124C2880”
  5. アプリケーション側でUIDに応じた処理を行う。

メリットとしては、データとUIDを2回読みこまなくともよい。(読み込みが速くなる。)

実際の例として、以下のような図があげれられています。

少し拡大して解説。

MIRROR_PAGEは “0C”を選択されています。0の開始ページ位置に合わせています。 Mirror Configuration byteは”54″でその中を見ると、MIRROR CONF “01b”, MIRROR_BYTEは “01b”となり、UID ASCII mirrorで開始位置が、1bitシフトされた位置ということにります。これにより、カードを読み込んだ際に “0”を埋め込んだ位置にUIDが表示されます。

NDEFについて

ちなみにこの中の数値はNDEFで定義されたあたいで、NDEFとはざっくりいうと、 “http”などの皆が共通に使用するような文字列を数値で圧縮して持ちましょうという規格と思っています。

で、いま、NDEFの仕様書をさらっと読もうとしたらはまってます。

  • 仕様書に書いてる部分の解説されている方(ここ参照)
  • 同じようなことを先にされているかたのデータを参照

まさかのNDEFではまる。

で、仕様書を読んでいてはまった。青の “Lock”, “LEN”って何??その部分のデータどうなっているのか??

ほぼ一日はまりまして、時間の無駄感があったので、先に行こうとしたときにわかりました。

Control TLVを記載した仕様書が肝

” 01 03 A0 0C 34 NTAG”で検索したら、それっぽい英語の文書が出てきました。皆さんここら辺ははまっておられる様子。。。ある意味安心します。

初めのリンクはこれでした。まったく仕様書に書かれている部分と同じバイト列。

# Control TLVs:
Lock Control TLV at address 0x04, offset 0
* Dynamic lock bytes at address 0x28, offset 0
– 12 lock bits (0x0C)
– 8 bytes locked per lock bit (0x3)
– Address calculation:
~ page address: 0xA
~ byte offset: 0x0
~ 16 bytes per page (1<<0x4) 01 03 A0 0C 34 |….4 |

Type 2 Tag Operation Specificationの仕様書では、 2.3.2 Lock Control TLVを参照すればどうも書いている様子。読んでみて、雰囲気的にこのType 2 Tag Operation Specificationのほうが、現行のNTAG21Xの仕様書より、古いので、その部分は古いほうの仕様を参考にして置き去りにされた感もあるので、ここはこれ以上突っ込まないでおこうと思います。

NDEFなんとなく理解した(Type2 Tag用)

そして、ようやく理解できたのがこちら、ちょっとさぼってる部分はあるけど、資料は示してあるので必要に応じて、自分で調べてみてください。

NFC counter mirror function(8.7.2)

今までの流れがわかってしまえばほとんど問題ありません。MIRROR_PAGE と MIRROR_BYTEを正しく設定して、 その位置に合うように”000000″(0を6個)並べれば、カウントした値が入ります。

UID and NFC counter mirror function (8.7.3)

こちらも同じ。MIRROR_PAGE と MIRROR_BYTEを設定して、0の並びの間にseparation characterとして、 “x” (78h)をUIDとcounterの間に入れれば、UIDとcount値が入ります。

UID mirror機能と、 NFC counter mirror機能が良いと思う理由

なぜかというと、事前にUIDを登録しておいて、Webサービス等で認証するIDとして、POSTなどをすることが可能だからです。

またカウント値は、サービスの利用回数等の目安にもなります。

下記のパスワードがかけられないような場合に、悪意ある第三者からの読み取り防止・ソフトウェア側でのロック等に使用できるかもしれません。

その他パスワード等について

ここら辺に書かれています。
Password verification protection (8.8)
Originality signature (8.9)
NTAG21x command overview (9.1)

そして、パスワードの認証等はこちらで試されています。大変参考になります。

パスワード認証・破壊的パスワード(negative password)があるということは、ある程度データ・ICの複製等に対応できるようにしているのだと思われます。

ちなみにPaSorRiでは

上記の参考記事では、Androidとかでやっておられるので、大丈夫なのですが、C#とかだとこのパスワード認証、たぶんコマンドでPWD_AUTHとかREAD_SIGをPCSCでPaSoriが実装しているのか重要になってくるわけです。NFC StarterKitの thruコマンドをしないといけなかったと思ってる(細かく調査してません)ので、今回はここもあまり突っ込まないでおきたいと思います。ACRとかならいける気がしてます。手元にACRもないので、余計に突っ込みません。

締め

わかったこと

  • NDEFのControl TLVを記載の古いほうの仕様書も大事
  • 静的ロック・動的ロックがある
  • 書きミスすると、それ以上書き込みできないこともある
  • UID ASCII mirror, Counter mirror機能がある
  • パスワード・Auth上限設定がある
  • Auth上限設定で上限を超えると使えなくなる
  • PaSoRiじゃなくて、ACRのほうが便利かも

上記の解説で使用したワークシートをダウンロードできるようにしておきます。お役立てください。

“NTAG21X 考えるためのワークシート” をダウンロード NTA213_215_216_考えるためのワークシート_20190225.zip – 345 回のダウンロード – 41 KB

ピップエレキバンとか言ったのが懐かしいぐらいですね。勉強になりました。パスワード以外の通常の使い方は網羅できたので、今回はここで終わりにします。また気が向いたり、読む必要があれば、突っ込んでいきたいと思います。
(2019/02/25時点)

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