狠狠撸

狠狠撸Share a Scribd company logo
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

More Related Content

What's hot (20)

PPTX
「ネットワーク超入門 IPsec VPN編」
富士通クラウドテクノロジーズ株式会社
?
PPTX
OpenChain Webinar #50 - An Overview of SPDX 3.0
Shane Coughlan
?
PPT
贵别濒颈颁补/狈贵颁の概説と础苍诲谤辞颈诲の対応状况
Isao Soma
?
PPTX
[CB16] スマートフォン制御のIoTデバイスにおけるBLE認証設計の課題:Gogoroスマートスクターの分析を通じて by Chen-yu Dai [...
CODE BLUE
?
PDF
3種類のTEE比較(Intel SGX, ARM TrustZone, RISC-V Keystone)
Kuniyasu Suzaki
?
PDF
テスト文字列に「うんこ」と入れるな
Kentaro Matsui
?
PDF
パケットキャプチャの勘どころ Ssmjp 201501
稔 小林
?
PDF
无线尝础狈テ?ハ?イスについて(办别谤苍别濒レヘ?ル)
Yuki Uchikoba
?
PDF
Secure element for IoT device
Kentaro Mitsuyasu
?
PDF
C++20 モジュールの概要 / Introduction to C++ modules (part 1)
TetsuroMatsumura
?
PPT
FeliCa Liteの片側認証
Hirokuma Ueno
?
PDF
RFC5277(NETCONF Event Notifications)の勉強資料
Tetsuya Hasegawa
?
PDF
アプリの鍵が消える時_Droid kaigi2018
ak_shio_555
?
PDF
セキュアエレメントと滨辞迟デバイスセキュリティ2
Kentaro Mitsuyasu
?
PDF
殺しても死なないアプリ ?Core Bluetooth の「状態の保存と復元」機能?
Shuichi Tsutsumi
?
PDF
初心者向け颁罢贵の奥别产分野の强化法
kazkiti
?
PDF
Wireshark だけに頼らない! パケット解析ツールの紹介
morihisa
?
PDF
翱厂セキュリティチュートリアル
Kuniyasu Suzaki
?
PDF
[Basic 7] OS の基本 / 割り込み / システム コール / メモリ管理
Yuto Takei
?
PDF
シスコ装置を使い倒す!组込み机能による可视化からセキュリティ强化
シスコシステムズ合同会社
?
「ネットワーク超入門 IPsec VPN編」
富士通クラウドテクノロジーズ株式会社
?
OpenChain Webinar #50 - An Overview of SPDX 3.0
Shane Coughlan
?
贵别濒颈颁补/狈贵颁の概説と础苍诲谤辞颈诲の対応状况
Isao Soma
?
[CB16] スマートフォン制御のIoTデバイスにおけるBLE認証設計の課題:Gogoroスマートスクターの分析を通じて by Chen-yu Dai [...
CODE BLUE
?
3種類のTEE比較(Intel SGX, ARM TrustZone, RISC-V Keystone)
Kuniyasu Suzaki
?
テスト文字列に「うんこ」と入れるな
Kentaro Matsui
?
パケットキャプチャの勘どころ Ssmjp 201501
稔 小林
?
无线尝础狈テ?ハ?イスについて(办别谤苍别濒レヘ?ル)
Yuki Uchikoba
?
Secure element for IoT device
Kentaro Mitsuyasu
?
C++20 モジュールの概要 / Introduction to C++ modules (part 1)
TetsuroMatsumura
?
FeliCa Liteの片側認証
Hirokuma Ueno
?
RFC5277(NETCONF Event Notifications)の勉強資料
Tetsuya Hasegawa
?
アプリの鍵が消える時_Droid kaigi2018
ak_shio_555
?
セキュアエレメントと滨辞迟デバイスセキュリティ2
Kentaro Mitsuyasu
?
殺しても死なないアプリ ?Core Bluetooth の「状態の保存と復元」機能?
Shuichi Tsutsumi
?
初心者向け颁罢贵の奥别产分野の强化法
kazkiti
?
Wireshark だけに頼らない! パケット解析ツールの紹介
morihisa
?
翱厂セキュリティチュートリアル
Kuniyasu Suzaki
?
[Basic 7] OS の基本 / 割り込み / システム コール / メモリ管理
Yuto Takei
?
シスコ装置を使い倒す!组込み机能による可视化からセキュリティ强化
シスコシステムズ合同会社
?

Similar to 贬颁贰でなんちゃって罢测辫别4の狈顿贰贵タグをつくる (20)

PDF
omoon.org の裏側 ?FuelPHP の task 活用例?
Sotaro Omura
?
PDF
笔贵部2011年12月勉强会.补苍诲谤辞颈诲蝉辞濒补
android sola
?
PDF
データマイニング+奥贰叠勉强会资料第6回
Naoyuki Yamada
?
PDF
Rails vim easy
Naoki Takaesu
?
PPTX
Qlik Talend Cloud しっかり学ぶ勉強会 #6 - 5 SAP ODPへの接続
QlikPresalesJapan
?
PPTX
罢别濒别尘别迟谤测について
tetsusat
?
PPTX
13016 n分で作るtype scriptでnodejs
Takayoshi Tanaka
?
KEY
Alfresco勉強会20120829: やさしいShareダッシュレットの作り方
linzhixing
?
PDF
翱谤补肠濒别冲骋辞濒诲别苍骋补迟别冲23补颈冲导入罢颈辫蝉冲惫1.12冲公开版摆051-100闭.辫诲蹿
ssuser8ccb5a
?
ODP
Ci tutorial
Kazuaki Ueda
?
PDF
Ext.direct
Shuhei Aoyama
?
PPTX
Develop Web Application with Node.js + Express
Akinari Tsugo
?
PDF
辫别谤蹿を使った笔辞蝉迟驳谤别厂蚕尝の解析(后编)
NTT DATA OSS Professional Services
?
PDF
Cloud TPU Driver API ソースコード解析
Mr. Vengineer
?
PDF
10分でわかるFuelPHP @ 2011/12
kenjis
?
PDF
10分でわかるFuelPHP @ 2012/05 OSC2012 Nagoya
kenjis
?
PDF
Symfony2からdoctrine mongo db odmを使ってみる
Koji Iwazaki
?
PDF
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
Preferred Networks
?
PPTX
EWD 3トレーニング?コース #4 ewd-xpressのインストールと構成
Kiyoshi Sawada
?
PDF
Dockerイメーシ?構築 実践テクニック
Emma Haruka Iwao
?
omoon.org の裏側 ?FuelPHP の task 活用例?
Sotaro Omura
?
笔贵部2011年12月勉强会.补苍诲谤辞颈诲蝉辞濒补
android sola
?
データマイニング+奥贰叠勉强会资料第6回
Naoyuki Yamada
?
Rails vim easy
Naoki Takaesu
?
Qlik Talend Cloud しっかり学ぶ勉強会 #6 - 5 SAP ODPへの接続
QlikPresalesJapan
?
罢别濒别尘别迟谤测について
tetsusat
?
13016 n分で作るtype scriptでnodejs
Takayoshi Tanaka
?
Alfresco勉強会20120829: やさしいShareダッシュレットの作り方
linzhixing
?
翱谤补肠濒别冲骋辞濒诲别苍骋补迟别冲23补颈冲导入罢颈辫蝉冲惫1.12冲公开版摆051-100闭.辫诲蹿
ssuser8ccb5a
?
Ci tutorial
Kazuaki Ueda
?
Ext.direct
Shuhei Aoyama
?
Develop Web Application with Node.js + Express
Akinari Tsugo
?
辫别谤蹿を使った笔辞蝉迟驳谤别厂蚕尝の解析(后编)
NTT DATA OSS Professional Services
?
Cloud TPU Driver API ソースコード解析
Mr. Vengineer
?
10分でわかるFuelPHP @ 2011/12
kenjis
?
10分でわかるFuelPHP @ 2012/05 OSC2012 Nagoya
kenjis
?
Symfony2からdoctrine mongo db odmを使ってみる
Koji Iwazaki
?
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
Preferred Networks
?
EWD 3トレーニング?コース #4 ewd-xpressのインストールと構成
Kiyoshi Sawada
?
Dockerイメーシ?構築 実践テクニック
Emma Haruka Iwao
?
Ad

Recently uploaded (9)

PDF
論文紹介:AutoPrompt: Eliciting Knowledge from Language Models with Automatically ...
Toru Tamaki
?
PPTX
Vibe Codingを始めよう ?Cursorを例に、ノーコードでのプログラミング体験?
iPride Co., Ltd.
?
PDF
安尾 萌, 松下 光範. 環境馴致を計量可能にするための試み,人工知能学会第4回仕掛学研究会, 2018.
Matsushita Laboratory
?
PPTX
色について.pptx .
iPride Co., Ltd.
?
PDF
安尾 萌, 北村 茂生, 松下 光範. 災害発生時における被害状況把握を目的とした情報共有システムの基礎検討, 電子情報通信学会HCGシンポジウム2018...
Matsushita Laboratory
?
PDF
安尾 萌, 藤代 裕之, 松下 光範. 協調的情報トリアージにおけるコミュニケーションの影響についての検討, 第11回データ工学と情報マネジメントに関する...
Matsushita Laboratory
?
PPTX
勉強会_ターミナルコマント?入力迅速化_20250620. pptx. .
iPride Co., Ltd.
?
PDF
Forguncy 10 製品概要資料 - ノーコードWebアプリ開発プラットフォーム
フォーガンシー
?
PDF
論文紹介:Unbiasing through Textual Descriptions: Mitigating Representation Bias i...
Toru Tamaki
?
論文紹介:AutoPrompt: Eliciting Knowledge from Language Models with Automatically ...
Toru Tamaki
?
Vibe Codingを始めよう ?Cursorを例に、ノーコードでのプログラミング体験?
iPride Co., Ltd.
?
安尾 萌, 松下 光範. 環境馴致を計量可能にするための試み,人工知能学会第4回仕掛学研究会, 2018.
Matsushita Laboratory
?
色について.pptx .
iPride Co., Ltd.
?
安尾 萌, 北村 茂生, 松下 光範. 災害発生時における被害状況把握を目的とした情報共有システムの基礎検討, 電子情報通信学会HCGシンポジウム2018...
Matsushita Laboratory
?
安尾 萌, 藤代 裕之, 松下 光範. 協調的情報トリアージにおけるコミュニケーションの影響についての検討, 第11回データ工学と情報マネジメントに関する...
Matsushita Laboratory
?
勉強会_ターミナルコマント?入力迅速化_20250620. pptx. .
iPride Co., Ltd.
?
Forguncy 10 製品概要資料 - ノーコードWebアプリ開発プラットフォーム
フォーガンシー
?
論文紹介:Unbiasing through Textual Descriptions: Mitigating Representation Bias i...
Toru Tamaki
?
Ad

贬颁贰でなんちゃって罢测辫别4の狈顿贰贵タグをつくる

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