• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
HCEでなんちゃってType4のNDEFタグをつくる
 

HCEでなんちゃってType4のNDEFタグをつくる

on

  • 1,581 views

Android 4.4 の新機能 HCE を使って Type 4 NDEF タグの動作をさせてみました。

Android 4.4 の新機能 HCE を使って Type 4 NDEF タグの動作をさせてみました。

Statistics

Views

Total Views
1,581
Views on SlideShare
1,576
Embed Views
5

Actions

Likes
3
Downloads
13
Comments
0

2 Embeds 5

https://twitter.com 3
https://www.google.com 2

Accessibility

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    HCEでなんちゃってType4のNDEFタグをつくる HCEでなんちゃってType4のNDEFタグをつくる Presentation Transcript

    • HCE で Type4 タグごっこ 2013/12/12 @hiero_adgjmptw
    • このスライドについて • このスライドでは、下記を行ないます – Android 4.4 の新機能である HCE の簡単な紹介 – それを使ったサービスの作成方法の紹介 – サービスのサンプルとして、なんちゃって Type4 タ グとして振る舞うサービスの作成 2
    • HCE の簡単な紹介 3
    • 簡単な紹介 • HCE (Host-based Card Emulation) は、Android 4.4 KitKat で導入された新機能 • 今まで FeilCa チップや UIM といった SE (Secure Element) 上で行っていたカード動作を Host (Android OS) 上で行う • これにより、端末がカードのように振る舞える – 具体的な例としては、チケットとか、会員証とか • プロトコルとしては ISO-DEP(ISO 14443-4) 上 に APDU コマンド(ISO7816-4) を流す形 – Type 4 タグ的な感じ • Host 上で動く(擬似)カードは HostApduService を継承したサービスとして誰 でも実装できる 4
    • SE はいらない!の図 今、一般的なカードエミュレー ション HCE を使ったカードエミュレー ション Android device Android device Host CPU NFC Controller NFC Reader Host CPU Secure Element NFC Controller Secure Element NFC Reader ※Secure Element を使わないので、Secure Element 非対応端末でもカードエミュレーションが出来 る ※一般的に管理が厳格な Secure Element と異なり、誰でもカードアプリを作成できる 5
    • 関連するプロトコル!の図 サービス開発者は ここを使って実装 する ISO7816-4 IC カード仕様 APDU コマンド定義とかここ ISO14443-3 Activation & Anti-collision いわゆる Type A とか B とか ISO14443-2 RF 層 ISO14443-1 物理層 システムでやってくれる ISO14443-4 通信プロトコル ISO-DEP だのなんだの 6
    • サービスの作り方 7
    • サービスの作り方 • 簡単 3ステップ! – HostApduService を継承したサービスを実装する – サービスの Manifest に Permission や Intentfilter を定義する – 反応する AID を定義した xml ファイルを作る 8
    • 準備 • Eclipse で Project を作る! – API は Level19 (4.4) 以上にする – Activity は不要なのでチェックはずす 新規AndroidProject Activity はいらない API Level は 19 (4.4) 9
    • サービスを実装する • HostApduService クラスを継承したサービスを 実装する – onTagDiscovered を実装して、ここでやりたいこと をする! 新規 Class HostApduService を継承 10
    • サービスを実装する public class HceNdefTagSample extends HostApduService { static enum CardStatus { INIT, SELECTED } final static byte[] SUCCESS = {(byte) 0x90, (byte) 0x00 }; CardStatus mCardStatus = CardStatus.INIT; @Override public void onDeactivated(int arg0) { // Reader から離れると、この API が呼び出される mCardStatus = CardStatus.INIT; } @Override public byte[] processCommandApdu(byte[] cmd, Bundle arg1) { // Reader からコマンドが送信されると、この API が呼び出される if(mCardStatus == CardStatus.INIT){ // 最初のコマンド == SELECT AID には 9000 を返す mCardStatus = CardStatus.SELECTED; return SUCCESS; } // 来たコマンドを 9000 をつけてオウム返しする ByteBuffer buf = ByteBuffer.allocate(cmd.length+SUCCESS.length); buf.put(cmd); buf.put(SUCCESS); return buf.array(); } } 11
    • Manifest に定義する • 作成したサービスの AndroidManifest.xml に下 記を行う: – android.permission.NFC の Permission を追加 – android.permission.BIND_NFC_SERVICE の Permission を追加 – android.nfc.cardemulation.action.HOST_APDU_SERV ICE の action で起動するように intent-filter を 追加 – 反応する AID を定義した xml ファイルを metadata として指定 12
    • Manifest に定義する <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.hcendeftagsample" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19" /> <uses-permission android:name="android.permission.NFC"/> NFC を使う <application android:allowBackup="true" 作ったサービスを登 android:icon="@drawable/ic_launcher" 録 android:label="@string/app_name" android:theme="@style/AppTheme" > Reader にかざされた <service android:name=".HceNdefTagSample" Permission を追加 時に起動するように android:exported="true" intent-filter 追加 android:permission="android.permission.BIND_NFC_SERVICE"> <intent-filter> <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <meta-data android:name="android.nfc.cardemulation.host_apdu_service" android:resource="@xml/apduservice"/> </service> 反応する AID を定義した </application> 外部 xml ファイルの指定 </manifest> 13
    • AID を定義した xml を作る • /res/xml/ の下に AID を定義した xml を作る – ファイル名は、さっき AndroidManifest.xml の meta-data で指定したもの xml フォルダを作って 新しく xml ファイルを 作成 14
    • AID を定義した xml を作る <host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/app_name" android:requireDeviceUnlock="false"> <aid-group android:description="@string/aid_description" android:category="other"> <aid-filter android:name=" F0010203040506 "/> </aid-group> 反応する AID を定義 </host-apdu-service> 複数の AID をまとめて aid-group を定義 #なぜかAID 単品では定義できない…(´・ω・ `) ##Description は文字列を直接指定できない ##ので String.xml に文字列定義を追加するこ と 15
    • Install/実行 • 前述の作業を完了したら、通常通り apk を insatll すれば OK – adb install ***.apk • あとは、登録した AID 向けの SELECT コマンド を NFC Reader/Writer から受信すれば、自動的 にサービスが起動して動作します • 実際に実行した時のコマンド・レスポンスは下 記の通り 処理(例) データの流 れ 対向→端末 00 A4 04 00 07 F0 01 02 03 04 05 06 対向←端末 90 00 対向→端末 00 01 02 03 04 01 02 03 04 対向←端末 00 01 02 03 04 01 02 03 04 90 00 16
    • サンプル:なんちゃってTYPE4タ グ 17
    • Type4 の NDEF タグ • HCE を使い、Type 4 の NDEF タグっぽい動きを するサービスを実装してみる • やらないといけないことは下記: – NDEF Tag Application の AID で反応するようにす る – NDEF Tag アプリケーションっぽく振る舞う Service を実装する 18
    • NDEF Tag Application に反応 • Type 4 の NDEF タグは固定名の AID のアプリ ケーション (NDEF Tag Application) を持って いる • NDEF Tag Application は AID: D2760000850101 • さっき作った apduservice.xml の AID をこの ID に変更すれば、NDEF Tag の読み出しに反応 できるようになる <host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/app_name" android:requireDeviceUnlock="false"> <aid-group android:description="@string/aid_description" android:category="other"> <aid-filter android:name=" D2760000850101 "/> </aid-group> NDEF Tag Application に反応するように指定 </host-apdu-service> 19
    • NDEF Tag App. の中身を実装 • onTagDiscovered() が NDEF Tag Application として振る舞うように動作するように実装する • 具体的には: – NDEF Tag Application が選択されたら動く – 中には2つのファイルがある: • Capability Container FILE … 読み書きの最大データサイ ズや NDEF FILE の ID などが格納されているファイル • NDEF FILE … NDEF 本体が格納されているファイル – なので、onTagDiscovered() ではそれぞれのファイ ルが選択、Read された際に適切にデータを返せるよ うにする 20
    • NDEF Tag App. の中身を実装 • NDEF タグ読み出し処理の流れは下記: データの流 れ 処理 対向→端末 対向 R/W から、NDEF Tag Application が SELECT される 対向←端末 90 00 を返却する 対向→端末 対向 R/W から CCFILE が SELECT される 対向←端末 90 00 を返却する 対向→端末 対向 R/W から READ BINARY(offset:0/size:16バイト)される 対向←端末 CCFILE の情報(アクセス制御情報、NDEF FILE識別子等)を返却する 対向→端末 対向 R/W NDEFFILE が SELECT される 対向←端末 90 00 を返却する 対向→端末 対向 R/W から READ BINARY(offset:0/size:2バイト)される 対向←端末 NDEF データのサイズを返却する 対向→端末 対向 R/W から READ BINARY(offset:2/size:NDEFサイズバイト) される 対向←端末 NDEF データを返却する 21
    • NDEF Tag App. の中身を実装 @Override public byte[] processCommandApdu(byte[] apdu, Bundle arg1) { switch(mCardStatus){ case INIT: // 初期状態 if(checkCmd(apdu, CMD_SELECT_BY_DF) && checkData(apdu, strToHex(TAGAPP_AID))){ mCardStatus = CardStatus.TAGAPP_SELECTED; return RES_SUCCESS; } return RES_NOTFOUND; case TAGAPP_SELECTED: // NDEF TAG App. が選択された状態 if(apdu[INS] == INS_SELECT){ return selectFile(apdu); } case CCFILE_SELECTED: // CCFILE が選択された状態、16バイト、通信の最大サイズとかが書かれてる if(apdu[INS] == INS_SELECT){ return selectFile(apdu); } if(apdu[INS] == INS_READ_BINARY){ int offset = apdu[P1]*256 + apdu[P2]; int length = apdu[LC]; return Arrays.copyOfRange(strToHex(CCFILE_DATA), offset, offset+length); } return RES_NOTFOUND; // 続く 22
    • NDEF Tag App. の中身を実装 case NDEFFILE_SELECTED: // NDEFFILE が選択された状態、先頭2バイトはサイズ、その後ろは NDEF そのもの if(apdu[INS] == INS_SELECT){ return selectFile(apdu); } if(apdu[INS] == INS_READ_BINARY){ int offset = apdu[P1]*256 + apdu[P2]; int length = apdu[LC]; return Arrays.copyOfRange(mNdefMessageData, offset, offset+length); } return RES_NOTFOUND; default: break; } return RES_NOTFOUND; } private byte[] selectFile(byte[] apdu) { if(checkCmd(apdu, CMD_SELECT_EF)){ if(checkData(apdu, strToHex(CCFILE_EF))){ mCardStatus = CardStatus.CCFILE_SELECTED; } if(checkData(apdu, strToHex(NDEFFILE_EF))){ mCardStatus = CardStatus.NDEFFILE_SELECTED; } return RES_SUCCESS; } return RES_NOTFOUND; } // その他、各種定義とか省略 23
    • 実行 • 実際に実行した時のコマンド・レスポンスは下 記の通り データの流 れ 対向→端末 00 A4 04 00 07 D2 76 00 00 85 01 01 00 (NDEF タグアプリ読むよ) 対向←端末 90 00 (おっけー) 対向→端末 00 A4 00 0C 02 E1 03 (CCFILE 開くよ) 対向←端末 90 00 (おっけー) 対向→端末 00 B0 00 00 0F (00~0F のデータ頂戴) 対向←端末 0F 20 00 40 00 40 E1 04 04 00 00 FF 00 00 00 (はいこれ~) 対向→端末 00 A4 00 0C 02 E1 04 (NDEF は E104 なのね?じゃあそれ開いて) 対向←端末 90 00 (おっけー) 対向→端末 00 B0 00 00 02 (じゃあ最初の2バイト=NDEFサイズ教えて) 対向←端末 00 0F (15バイトだよ) 対向→端末 00 B0 00 02 12 (じゃあ2バイト目から15バイトの NDEF 読むね) 対向←端末 D1 01 0B 55 01 67 6F 6F 67 6C 65 2E 63 6F 6D 00 00 00 (はい、これが NDEF) 24
    • 最後に 25
    • やってみた感想 • とりあえず Reader/Writer に反応するようにす るのはとても簡単 • セキュリティ的にうるさく無いシステムなら、 今 Type A カードでやってるようなサービス (入出門管理とか)は簡単にモバイル対応でき る気がする • セキュリティが大切なやつはクラウド側でやれ ばいいか? • 作ったなんちゃって Type 4 タグを Android 端 末で読もうとしたら「タップしてビーム」とか 言われてがっかり – enableReaderMode できる 4.4 端末が欲しい(´・ 26
    • 参考資料 • Android Developers http://developer.android.com/intl/ja/guide/topics/connectivity/nfc /hce.html • 上記ページの和訳サイト http://dev.classmethod.jp/smartphone/kitkat-host-based-cardemulation/ • ブライテクノblog http://brightechno.com/blog/archives/179 • ISO7816-4 http://www.ttfn.net/techno/smartcards/iso7816_4.html • NFC Forum http://www.nfc-forum.org/home/ 27
    • ソース • githubとかにあげるといいのかなぁ…(´・ω・ `) 28