0
HCE で Type4 タグごっこ
2013/12/12
@hiero_adgjmptw
このスライドについて
• このスライドでは、下記を行ないます
– Android 4.4 の新機能である HCE の簡単な紹介
– それを使ったサービスの作成方法の紹介
– サービスのサンプルとして、なんちゃって Type4 タ
グとして振る舞...
HCE の簡単な紹介

3
簡単な紹介
• HCE (Host-based Card Emulation) は、Android
4.4 KitKat で導入された新機能
• 今まで FeilCa チップや UIM といった SE
(Secure Element) 上で行っ...
SE はいらない!の図
今、一般的なカードエミュレー
ション

HCE を使ったカードエミュレー
ション

Android device

Android device

Host CPU

NFC
Controller

NFC Reader...
関連するプロトコル!の図
サービス開発者は
ここを使って実装
する
ISO7816-4 IC カード仕様
APDU コマンド定義とかここ

ISO14443-3 Activation & Anti-collision
いわゆる Type A と...
サービスの作り方

7
サービスの作り方
• 簡単 3ステップ!
– HostApduService を継承したサービスを実装する
– サービスの Manifest に Permission や Intentfilter を定義する
– 反応する AID を定義した ...
準備
• Eclipse で Project を作る!
– API は Level19 (4.4) 以上にする
– Activity は不要なのでチェックはずす

新規AndroidProject

Activity はいらない

API Le...
サービスを実装する
• HostApduService クラスを継承したサービスを
実装する
– onTagDiscovered を実装して、ここでやりたいこと
をする!

新規 Class

HostApduService を継承

10
サービスを実装する
public class HceNdefTagSample extends HostApduService {
static enum CardStatus { INIT, SELECTED }
final static b...
Manifest に定義する
• 作成したサービスの AndroidManifest.xml に下
記を行う:
– android.permission.NFC の Permission を追加
– android.permission.BIN...
Manifest に定義する
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hcendeftagsample"...
AID を定義した xml を作る
• /res/xml/ の下に AID を定義した xml を作る
– ファイル名は、さっき AndroidManifest.xml の
meta-data で指定したもの

xml フォルダを作って
新しく...
AID を定義した xml を作る
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@stri...
Install/実行
• 前述の作業を完了したら、通常通り apk を
insatll すれば OK
– adb install ***.apk

• あとは、登録した AID 向けの SELECT コマンド
を NFC Reader/Writ...
サンプル:なんちゃってTYPE4タ
グ
17
Type4 の NDEF タグ
• HCE を使い、Type 4 の NDEF タグっぽい動きを
するサービスを実装してみる
• やらないといけないことは下記:
– NDEF Tag Application の AID で反応するようにす
る
...
NDEF Tag Application に反応
• Type 4 の NDEF タグは固定名の AID のアプリ
ケーション (NDEF Tag Application) を持って
いる
• NDEF Tag Application は
AI...
NDEF Tag App. の中身を実装
• onTagDiscovered() が NDEF Tag Application
として振る舞うように動作するように実装する
• 具体的には:
– NDEF Tag Application が選択さ...
NDEF Tag App. の中身を実装
• NDEF タグ読み出し処理の流れは下記:
データの流
れ

処理

対向→端末

対向 R/W から、NDEF Tag Application が SELECT される

対向←端末

90 00 ...
NDEF Tag App. の中身を実装
@Override
public byte[] processCommandApdu(byte[] apdu, Bundle arg1) {
switch(mCardStatus){
case INIT...
NDEF Tag App. の中身を実装
case NDEFFILE_SELECTED: // NDEFFILE が選択された状態、先頭2バイトはサイズ、その後ろは NDEF そのもの
if(apdu[INS] == INS_SELECT){
...
実行
• 実際に実行した時のコマンド・レスポンスは下
記の通り
データの流
れ
対向→端末

00 A4 04 00 07 D2 76 00 00 85 01 01 00 (NDEF タグアプリ読むよ)

対向←端末

90 00 (おっけー)...
最後に

25
やってみた感想
• とりあえず Reader/Writer に反応するようにす
るのはとても簡単
• セキュリティ的にうるさく無いシステムなら、
今 Type A カードでやってるようなサービス
(入出門管理とか)は簡単にモバイル対応でき
る気...
参考資料
• Android Developers
http://developer.android.com/intl/ja/guide/topics/connectivity/nfc
/hce.html

• 上記ページの和訳サイト
http...
ソース
• githubとかにあげるといいのかなぁ…(´・ω・
`)

28
Upcoming SlideShare
Loading in...5
×

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

3,730

Published on

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

Published in: Technology, News & Politics
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,730
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
23
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

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

  1. 1. HCE で Type4 タグごっこ 2013/12/12 @hiero_adgjmptw
  2. 2. このスライドについて • このスライドでは、下記を行ないます – Android 4.4 の新機能である HCE の簡単な紹介 – それを使ったサービスの作成方法の紹介 – サービスのサンプルとして、なんちゃって Type4 タ グとして振る舞うサービスの作成 2
  3. 3. HCE の簡単な紹介 3
  4. 4. 簡単な紹介 • 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
  5. 5. 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
  6. 6. 関連するプロトコル!の図 サービス開発者は ここを使って実装 する ISO7816-4 IC カード仕様 APDU コマンド定義とかここ ISO14443-3 Activation & Anti-collision いわゆる Type A とか B とか ISO14443-2 RF 層 ISO14443-1 物理層 システムでやってくれる ISO14443-4 通信プロトコル ISO-DEP だのなんだの 6
  7. 7. サービスの作り方 7
  8. 8. サービスの作り方 • 簡単 3ステップ! – HostApduService を継承したサービスを実装する – サービスの Manifest に Permission や Intentfilter を定義する – 反応する AID を定義した xml ファイルを作る 8
  9. 9. 準備 • Eclipse で Project を作る! – API は Level19 (4.4) 以上にする – Activity は不要なのでチェックはずす 新規AndroidProject Activity はいらない API Level は 19 (4.4) 9
  10. 10. サービスを実装する • HostApduService クラスを継承したサービスを 実装する – onTagDiscovered を実装して、ここでやりたいこと をする! 新規 Class HostApduService を継承 10
  11. 11. サービスを実装する 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
  12. 12. 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
  13. 13. 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
  14. 14. AID を定義した xml を作る • /res/xml/ の下に AID を定義した xml を作る – ファイル名は、さっき AndroidManifest.xml の meta-data で指定したもの xml フォルダを作って 新しく xml ファイルを 作成 14
  15. 15. 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
  16. 16. 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
  17. 17. サンプル:なんちゃってTYPE4タ グ 17
  18. 18. Type4 の NDEF タグ • HCE を使い、Type 4 の NDEF タグっぽい動きを するサービスを実装してみる • やらないといけないことは下記: – NDEF Tag Application の AID で反応するようにす る – NDEF Tag アプリケーションっぽく振る舞う Service を実装する 18
  19. 19. 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
  20. 20. NDEF Tag App. の中身を実装 • onTagDiscovered() が NDEF Tag Application として振る舞うように動作するように実装する • 具体的には: – NDEF Tag Application が選択されたら動く – 中には2つのファイルがある: • Capability Container FILE … 読み書きの最大データサイ ズや NDEF FILE の ID などが格納されているファイル • NDEF FILE … NDEF 本体が格納されているファイル – なので、onTagDiscovered() ではそれぞれのファイ ルが選択、Read された際に適切にデータを返せるよ うにする 20
  21. 21. 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
  22. 22. 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
  23. 23. 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
  24. 24. 実行 • 実際に実行した時のコマンド・レスポンスは下 記の通り データの流 れ 対向→端末 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. 25. 最後に 25
  26. 26. やってみた感想 • とりあえず Reader/Writer に反応するようにす るのはとても簡単 • セキュリティ的にうるさく無いシステムなら、 今 Type A カードでやってるようなサービス (入出門管理とか)は簡単にモバイル対応でき る気がする • セキュリティが大切なやつはクラウド側でやれ ばいいか? • 作ったなんちゃって Type 4 タグを Android 端 末で読もうとしたら「タップしてビーム」とか 言われてがっかり – enableReaderMode できる 4.4 端末が欲しい(´・ 26
  27. 27. 参考資料 • 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
  28. 28. ソース • githubとかにあげるといいのかなぁ…(´・ω・ `) 28
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×