はじめに
モバイルアプリを多数手掛ける 株式会社 impl では、ICカードの読み取りが要件に入ることも少なくありません。
今回は、ICカードの中でも日本での普及率が高い「Felica」の読み取りを実装するにあたって押さえておきたい基本的な知識を紹介します。
全体の概要を掴むことができますので今後の設計や実装に役立ててください。
Felica とは
ICカードには、多数の仕様があり、Felicaはその一つです。Sonyが開発・管理を行なっており、高いセキュリティが特徴です。日本においてはSuicaなど、交通系ICカードなどで採用されています。
ICカードの規格
主に以下が広く普及しています。
- Type A(Mifare)
- Type B
- Felica
規格によって接続の方法が異なるため、まずは扱うカードがどの規格に相当するか確認することが重要です。
カードの読取
Felica カードの読み取りを行います。
カードリーダの検出と接続
カードの読み取りには、当然ですがカードリーダとアプリケーションの実行端末を接続する必要があります。カードリーダによって、必要なSDKや通信方式が異なるため、ここも実は注意が必要です。
最近はスマホ端末で読み取ることも、多いですね。
カードリーダの対応規格を確認
- Type A(Mifare)
- Type B
- Felica
それぞれ使用するICカードの規格に対応しているカードリーダを使用しましょう。
カードの検出
ICカードをカードリーダにかざすことで、リーダがカードを検出します。ただし、この時点ではまだアプリケーションの実行端末とカードは接続できていません。
カードと接続
アプリケーションとICカードを接続します。カードリーダとアプリケーションを接続した上で、カードともコネクションを確立する必要があります。
接続が完了すると、ATR を取得できます。
カードATR とは
ATRは(Answer To Reset)の略です。これは例えば以下のような文字列で、カードの状態、プロトコル(先述のカード規格)等の情報を含んでいます。
3B 8F 80 01 80 4F 0C A0 00 00 03 06 11 00 3B 00 00 00 00 42
リセット ?
Answer To Reset がなぜ カードの状態、プロトコル(先述のカード規格)等の情報 を含むのか、疑問に思った方もいるかもしれません。
ここで「リセット」と言っているのは、「ICカードが電気的に復旧した」という意味合いです。ICカードは、カードリーダに近接することで通電し、応答します。この応答(Answer)が ATRです。
カードとの通信
Felicaと接続できたら、ようやく通信を行うことができます。コマンドをリクエストとして送信することで、カードからレスポンスを得ることが可能です。
APDU(Application Protocol Data Unit)
APDU(Application Protocol Data Unit)は ICカードとの通信に使われるコマンドの国際規格です。このAPDUコマンドを作成し、カードに送信することで通信を行います。以下はAPDUの例です。
Send APDU: <<< FF AB 00 00 0F 06 01 01 02 12 E4 1C 36 0C 01 8F 10 01 80 00
Resp APDU: >>> 1D 07 01 01 02 12 E4 1C 36 0C 00 00 01 A0 00 24 C9 10 01 2C 8D 18 36 00 00 00 00 00 00 90 00
上記は、ある Fericaカードに APDUコマンドを送信し、カードからレスポンスAPDUが返却された様子です。
IDmを取得する
Felicaには「IDm」という他のカード規格にはない値があります。これはソニーが管理するカードの識別番号であり、カードのセキュリティに一役買っています。
FelicaカードのIDmを取得する APDUは以下の通りです。
Send APDU: <<< FF CA 00 00 00
Resp APDU: >>> 01 01 02 12 E4 1C 36 0C 90 00
以降のリクエストに IDmを含める
カードに送信するリクエストによっては、そのリクエストに IDmを含める必要があります。そのため、まずは カード IDmを取得することから通信を開始するよ良いでしょう。
APDU を作成し送信する
ここからはカードに送信したいリクエストに応じて、APDUを自身で構築する必要があります。カードの種類によって、受け付けるAPDUは異なるのでカードの仕様を確認する必要があります。
APDU の構成
APDUはおおむね以下のように構成されます。
項目名 | サイズ | 説明 |
---|---|---|
CLA | 1byte | 命令クラス |
INS | 1byte | 命令コード |
P1 | 1byte | コマンドのパラメータ1 |
P2 | 1byte | コマンドのパラメータ2 |
Lc | n byte | Data のサイズ |
Data | n byte | 送信するデータ |
Le | n byte | レスポンスの最高サイズ |
例えば、先ほどの IDmを取得する APDUは以下のような構成になっています。
FF CA 00 00 00
- CLA: FF
- INS: CA
- P1: 00
- P2: 00
- Lc: なし
- Data: なし
- Le: 00 (指定なし)
レスポンスAPDUを確認する
APDUをカードに送信することで、カードからレスポンスが返却されます。レスポンスにはステータスコードが必ず含まれるよう国際規格で定められています。
Resp APDU: >>> 01 01 02 12 E4 1C 36 0C 90 00
末尾の 2バイト(90 00)がステータスコードです。
- 90 00: 正常終了
- 6A 82: ファイルが存在しない
など、さまざまあります。詳細は以下のリンク先にまとまっています。
バイト列の解読
レスポンスは バイト列になっているため、人間が読めるようこれを変換する必要があります。
レスポンス中の何バイト目に必要な情報が入っているか、あるいは何ビット目、という場合もあります。ビット指定の場合は、16進数から 2進数に変換した上で、ビットを数える必要があります。
例えば、 2C 8D
という2バイトをビットに直すと以下のようになります。
0010110010001101
↑の上位4ビット、と指定があれば 0010
が必要な情報となり、さらにこれを必要な形式に変換して使用します。
ビットとかバイトとか
聞き慣れない場合は以下もご覧ください。
カードとの接続を解除する
通信が完了したら、カードとの接続を解除します。例えば複数のカードを連続して読み取る場合は、まず現在のカードを接続解除しておく必要があります。
ただカードリーダからカードを離すだけで、カード側の通電はもちろん無くなりますが、アプリケーションの実装によってはまだ接続が終了していない場合があるためです。
カードリーダとの接続を解除する
アプリケーションを終了する際には、カードリーダとの接続も解除します。
まとめ
ICカードとの接続と読み取りのライフサイクルを紹介しました。
タッチするだけで情報が流れてくるようなイメージがありますが、実際には複雑な仕様を理解して通信を行う必要があります。
また、レスポンスは バイト列になっているため、人間が読めるようこれを変換する実装も必要です。
「読み取るだけ…」と思うと大変だったりするので(書き込みはもっと大変)用心して臨むと良いでしょう。