ご指摘いただきありがとうございました。
完全に「PASUMO」だと勘違いしてました。「PASMO」が正しいんですね。
Suica/PASMO の券面に印字された情報が NFC の機能で取得できるのか調査した時のログの内 FeliCa (Suica/PASMO) の仕様をまとめたもの です。
私は PASMO ユーザなので、PASMO での調査ログになりますことをご了承ください。
次のことをまとめようと思います。
- NFC について
- FeliCa について
- FeliCa のデータ構造について
- Suica/PASMO のデータ構造について
- FeliCa との通信の流れについて
- まとめ
NFC について
Near Field Communication と呼ばれる技術です。
近距離無線通信
や 非接触通信
と訳されます。
FeliCa は NFC なのか?
という質問をたまに見ますが、
- NFC は近距離無線通信の規格のことです。
- Felica は Sony が推進している NFC に準拠した方式です。
Sony :FeliCa: NFCの定義 にて記載されている NFC のコンセプトは次のような図になるそうです。
NFC には NFC-A
, NFC-B
, NFC-F
という方式があって、どのようなデバイスでも実装可能なものを目指しているようです。
FeliCa は NFC-F
という規格に該当します。
FeliCa について
FeliCa は、Wikipedia: NFC のページにて、次のように解説されています。
ISO/IEC 18092[編集]
NFC (Near Field Communication) と呼ばれる無線通信の国際規格である。十数センチの距離での小電力無線通信技術である。2003年12月に規格化された。NFC IP-1 (Interface Protocol-1)。
ソニー(FeliCaを推進)とNXPセミコンダクターズ(MIFAREを推進、旧フィリップス)の共同開発によって、FeliCaやISO/IEC 14443 (MIFARE) のような既に普及しているICカード非接触無線通信技術との下位互換性を維持している。使用周波数はMIFAREなどと同じ13.56MHzである。
ということで FeliCaとは、Sony が推進している NFC の一つの方式です。(参考: Sony: FeliCa, Wikipedia: FeliCa)
Sony の FeliCa についての解説ページで、次のような特徴が挙げられています。
通信は、13.56 MHzの周波数帯を利用し、212 kbps / 424 kbpsの速度で行われます。副搬送波を使用しない「対称通信」が特長です。
通信速度って、数値出されてもいまいちピンとこないんですけどね。
要するに、処理が早い通信方式だよということのようです。
FeliCa の情報を調べる際は、FeliCa の ICチップを開発している フェリカネットワークス も参照するとよいかと思います。
FeliCa のデータ構造について
FeliCa のデータには、大きく 共通領域(フリー領域) 、プライベート領域 があります。
Sony: FeliCaポケット の紹介ページに次のようなイメージ図があります。
「FeliCa プライベート領域 共通領域」で画像検索すると出てくるように、個人情報や金融関係などはプライベート領域に、そうでない情報は共通領域に格納しましょうということだそうです。
この 共通領域 は、フェリカネットワークスが管理をする領域で、複数のサービスの情報が同居できる領域です。
フェリカネットワークス: 技術情報 の 共通領域ガイドライン
にてガイドラインが公開されています。
- オレンジの領域: フェリカネットワークスが管理・設定する
- ライトグリーンの領域: サービス提供者が設定する
イメージとしては上の図のようになっています。
また、上の図はいわゆる FeliCa のファイルシステムの構造を表します。
領域は次の4つがあります。
- システム
- エリア
- サービス
- ブロック
システム
システム とは、論理的なカードの単位を表します。
物理的なカードが製造された最初の状態では、 システム 0
のみが存在します。
システムを追加する際は、システム 0 の残分が割り当てられます。
システムコード
システムコード とは、システムを特定するための 2byte の値です。
事業者/使用目的ごとに割り当てられます。
Suica/PASMO などの交通系は 00 03
という値だそうです。
※ 明確に記載している仕様書が見当たらないですが・・・。
JIS X 6319-4:2010
という規格にて FE 00
~ AA 00
という予約領域が定義されています。
FE 00
はフェリカネットワークス社が管理する共通領域を示すシステムコードです。
エリア
エリア とは、不揮発性メモリ領域の使用可能な残ブロック数やサービスへのブロック数の割当てのことを指します。
エリア情報には、子エリアの作成が可能かどうか
や、割当ブロック数
、エリア鍵
、エリア鍵バージョン
が含まれます。
サービス
サービス とは、ファイルシステム上のブロックをグループ化したものです。
グループ化されたブロックに対するアクセスコントロールを提供します。
サービスが管理するブロックにアクセスするには、2byte
の サービスコード
でサービスを特定します。
また、2byte
の ブロック番号
を指定することでサービスが管理する範囲内のブロックにアクセスします。
※ ブロック番号はサービス内で 0
スタートの連番です。
サービスコード
サービスコード とは、サービスを特定するための 2byte の値です。
上位 10bit をサービス番号、下位 6bit をサービス属性として構成されます。
Suica の入出場記録のサービスコードは 09 0F
なので、bit に直すと 0 0 0 0 1 0 0 1 0 0 0 0 1 1 1 1
となり、次のような区分になります。
v サービス番号
Service Code: [[0 0 0 0 1 0 0 1 0 0] [0 0 1 1 1 1]]
^ サービス属性
サービス属性はアクセス方法と認証に関する属性です。
サービス属性 | サービス属性の値 | |
---|---|---|
ランダムサービス | リード/ライトアクセス: 認証必要 | 0 0 1 0 0 0 |
リード/ライトアクセス: 認証不要 | 0 0 1 0 0 1 |
|
リードオンリーアクセス: 認証必要 | 0 0 1 0 1 0 |
|
リードオンリーアクセス: 認証不要 | 0 0 1 0 1 1 |
|
サイクリックサービス | リード/ライトアクセス: 認証必要 | 0 0 1 1 0 0 |
リード/ライトアクセス: 認証不要 | 0 0 1 1 0 1 |
|
リードオンリーアクセス: 認証必要 | 0 0 1 1 1 0 |
|
リードオンリーアクセス: 認証不要 | 0 0 1 1 1 1 |
|
パースサービス | ダイレクトアクセス: 認証必要 | 0 1 0 0 0 0 |
ダイレクトアクセス: 認証不要 | 0 1 0 0 0 1 |
|
キャッシュバック/デクリメントアクセス: 認証必要 | 0 1 0 0 1 0 |
|
キャッシュバック/デクリメントアクセス: 認証不要 | 0 1 0 0 1 1 |
|
デクリメントアクセス: 認証必要 | 0 1 0 1 0 0 |
|
デクリメントアクセス: 認証不要 | 0 1 0 1 0 1 |
|
リードオンリーアクセス: 認証必要 | 0 1 0 1 1 0 |
|
リードオンリーアクセス: 認証不要 | 0 1 0 1 1 1 |
上の表にある3つのサービスについてまとめます。
ランダムサービス とは、ユーザが自由にブロックを指定してアクセス可能なサービスです。
サイクリックサービス とは、一番古いブロックに対して書き込みを行うサービスです。ログの記録などに利用します。
パースサービス とは、ブロックデータの一部を製の数値とみなして、その値を減産する機能を持つサービスです。
上記表にはありませんが、オーバラップサービス と言うものもあります。
複数のブロックデータを複数のサービスで共有して管理することを オーバラップする といい、対象のサービスを オーバラップサービス と呼びます。
より詳しい情報は FeliCa カード ユーザーズマニュアル 抜粋版: 3.4.3, 3.4.4, 3.4.5
を参照してください。
ブロック
ブロック とは、書き込み/読み出しにおける 16byte の単位です。
ユーザ情報の全てはこのブロックに格納されます。
また、鍵情報やファイルシステムの管理情報なども格納されます。
ユーザのアクセス単位もブロックとなるので、16byte を超える情報を格納するには複数のブロックに分割する必要があります。
不揮発性メモリ領域上のブロックの管理は全てファイルシステムが行います。
ユーザが使用するブロックにアクセスするには エリア や サービス を使用します。
システム分割機能により、複数のシステムの情報が同居できるようになっていて、各システムは複数のエリア、サービスを持つことができるようになっています。
次に、各種識別子についてまとめます。
- IDm (製造ID/Manufacture ID)
- PMm (製造パラメータ/Manufacture Parameter)
それぞれのコードについて Sony の FeliCa技術方式の各種コードについて(FeliCa Technology Code Descriptions) という資料を参考にまとめます。
IDm について
IDm (製造ID/Manufacture ID) とは、通信相手のカードを識別するためのIDです。
Polling(後述します)レスポンスの レスポンスコード
に続く 8バイトの値です。
上位2バイトを 製造者コード、続く6バイトを カード識別番号 と呼びます。
カードに複数のシステムが存在する場合は、個々のシステムに IDm が設定されます。
この場合、製造者コードの 上位4バイト はカード内システム番号を示します。
※ 「上位4バイト」に関して指摘いただきました。製造者コードは2バイトと言っておきながら上位4バイトってどういうこと?!って感じです。改めて情報確認しますのでしばし正しい情報をお待ち下さい。 (2019-10-07)
製造者コードの下位1バイトが FE
となるものは、カード識別番号の体型が定められています。
それ以外の値の場合は、 Sony がカード製造者が規定する体系に則ってカード識別番号を付与します。
例えば、私の PASMO の IDm は 01 10 04 10 2C 14 1E 30
なので、次のような区分けになります。
v 製造者コード
IDm: [[01 10] [04 10 2C 14 1E 30]]
^ カード識別番号
製造者コードの下位1バイトは FE
ではないので、Sony が採番したカード識別番号であるということになります。
※ カード識別番号の体系によって、カード識別番号がカードごとにユニークな値とならない場合があると明記されています。
文書に製造者コードとカード識別番号の体系とカード製品の用例として、次の表が紹介されています。
製造者コード | カード識別番号の体系 | カード製品の用例 |
---|---|---|
01 FE | 乱数(ISO/IEC 18092 (NFCIP-1) で規定) | NFCIP-1 対応製品 |
02 FE | 番号体系の来ていなし | NFC Forum Type 3 Tag |
03 FE | Sony が規定するデータフォーマットコードを含む番号体系 | FeliCa Plug |
上記以外の XX FE
|
予約 | |
上記以外 | カード製造者(IDm の付与者)が規定する番号体系 | FeliCa Standard カードなど |
PMm について
PMm (製造パラメータ/Manufacture Parameter) とは、通信相手の性能を識別するためのパラメータです。
Polling(後述します)レスポンスの IDm
に続く 8バイトの値です。
上位2バイトを ICコード、続く6バイトを 最大応答時間パラメータ と呼びます。
ICコードは、ICチップの種類を識別するためのコードです。上位 1byte はROM種別を、下位1byte は IC種別を示します。
ICコードが FF FF
のものは JIS X 6319-4:2005 改正版およびNFC Forum
の仕様で利用されています。
それ以外の値は、ICチップの種類ごとに割り当てられ、Sony によって管理されています。
例えば、私の PASMO の PMm は 10 0B 4B 42 7C 7B 30 01
なので、次のような区分けになります。
v ICコード
PMm: [[10 0B] [4B 42 7C 7B 30 01]]
^ 最大応答時間パラメータ
IC種別によってどの FeliCa かを判断することができます。
Sony: 技術情報対象製品一覧: FeliCa (FeliCa Standard) を参照しましょう。
私の PASMO の IC種別は 0B
ですが、上の一覧からは見つかりませんでした・・・。ココらへん間違っているのかしら。
最大応答時間パラメータは、コマンドにより扱いが変わります。
6byte の内訳は上図の通りで、次の計算式で最大応答時間を求めます。
最大応答時間(ms) = T × [(B + 1) × n + (A + 1) × 4^E
n
はコマンドにより意味付けが変わります。
表の 位置
の列がなにを意味しているのかよくわからないですが、そのまま載せます。
位置 | コマンド種別 | コマンド名称 | 計算式における n の意味づけ |
---|---|---|---|
D10 | パケット要素によって応答時間が変わるコマンド |
Request Service Request Service v2
|
ノード数 |
D11 | パケット要素によって応答時間が変わらないコマンド |
Request Response Search Service Code Request System Code Gte System Status Request Specification Version Reset Mode update Random ID
|
0 |
D12 | 相互認証用コマンド |
Authentication1 Authentication2 Authentication1 v2 Authentication2 v2
|
ノード数 0 ノード数 0 |
D13 | 読み出し用コマンド |
Read Without Encryption Read Read v2
|
ブロック数 |
D14 | 書き込み用コマンド |
Write Without Encryption Write Write v2
|
ブロック数 |
D15 | その他コマンド | 発行コマンド | 0 |
Polling コマンドに関しては、アンチコリジョン処理のため複雑になっています。
知る必要がある場合は FeliCa カード ユーザーズマニュアル 抜粋版 2.3.5 アンチコリジョン処理
を参照してください。
各コマンドについての解説は割愛しますが、単純にデータを取得する際の解説は後述します。
各種識別系の値を解説しました。
Suica/PASMO のデータ構造について
JR東日本 IT・Suica事業の要覧 によると
「スイスイ」行ける「IC」「カード」の意味。
Super Urban Intelligent CArdの略。
だそうです。
Suica/PASMO の交通系カードはサイバネ規格というものだそうです。
日本鉄道サイバネティクス協議会という協議会で策定された規格で CJRC規格
と呼ばれることもあります。
駅コードなどもサイバネ規格の中に入るようです。
そしてこの Suica/PASMO のデータ構造や値の定義をしているサイバネ規格は公開されていないようで、実際に取得できる駅コードや店舗コードなどが何を指しているのかは有志によってデータベース化されているみたいです。IC SFCard Fan DB Service
駅コード、店舗コードの他にもシステムコードをまとめている人もいて、Suica/PASMO を対象として開発をする場合、お世話になることになるかと思います。
ついでに
規格策定の関係者になるには、多額を支払い協議会の一員にならない溶けないそうです。
ホームページ をみてもだいたい会員専用という・・・。
ちなみに、システムコードの話で挙げた JIS X 6319-4:2010
をネット上で探すと 購入ができるページ に行き着きます。
なんだか不透明な世界ですね。
セキュリティ的にしょうがないのかもしれないですが。
FeliCa との通信の流れについて
読み取りを目的とした通信の場合にフォーカスして解説します。
おおまかな流れは次の通りです。
- Polling コマンドを実施し、通信対象として捕捉する
- Request Service コマンドを実施し、利用したいサービスコードの正当性を確認する
- Read Without Encryption コマンドを実施し、暗号化されていない領域の上方を読み取る
FeliCa のモードについて...
カードには 4種類のモードがあります。
提供されるコマンドは、モードによって実行が制限されています。
Mode 名 | 状態に遷移する契機 | 制限・備考 |
---|---|---|
状態なし | 電源供給が絶たれた時 | |
Mode 0 | 電源が供給された時 | Polling を実行できる。Polling の結果 IDm を取得すると Authentication1 (v2) を実行できる。 他のモードのときでも、別のシステムに対する Polling は実施可能。 |
Mode 1 | Authentication1 (v2) 実行後 | |
Mode 2 | 相互認証完了後 | Read (v2), Write (v2) を実行できる。 |
Mode 3 | エリア・サービスの登録、システム分割実施後 |
Polling を行い IDm を取得し、IDm を使用して認証を実施することで Mode 1, 2 どちらかに遷移する。
Mode 0 ではなくなった時点で、カードは Polling を受け付けなくなる。
すなわち、認証を行うと他のリーダ/ライタは同カードの操作権限を得られなくなる。
これにより、リード/ライト の衝突を低減している。
しかし、別のシステムに対する Polling を受け付けることは可能である。
モードの遷移の解説は FeliCa カード ユーザーズマニュアル 抜粋版 4.3.1, 4.3.2, 4.3.3
にまとめられている。
幾つかのコマンドについて
リクエストパケット/レスポンスパケットについて
共通事項として、両パケットは最初の 1byte にデータ長を設定します。
※ ユーザーズマニュアル の Polling の項目にも Read Without Encryption の項目にも記載がなく、はままりました。
Polling コマンド
リーダ/ライタがカードを捕捉・特定するためのコマンドです。
実行することで、IDm
, PMm
を取得することができます。
リクエストパケット
パラメータ名 | サイズ (byte) | データ | 備考 |
---|---|---|---|
コマンドコード | 1 | 00 |
|
システムコード | 2 | ||
リクエストコード | 1 | リクエストデータの指定00 : 要求なし01 : システムコード要求02 : 通信性能要求その他 : 予約 |
|
タイムスロット | 1 | 応答可能な最大スロット数の指定 |
レスポンスパケット
パラメータ名 | サイズ (byte) | データ | 備考 |
---|---|---|---|
レスポンスコード | 1 | 01 |
|
IDm | 8 | 対象システムの IDm | |
PMm | 8 | ||
リクエストデータ | 2 | コマンドパケットのリクエストコードが 00 以外で、且つ製品が対応するリクエストコードが指定された場合のみ返送されます。 |
システムコードには FF
というワイルドカードが指定できます。
Request Service コマンド
エリアやサービスの存在確認と鍵バージョンを取得するためのコマンドです。
指定したエリアやサービスが存在する場合には、鍵バージョンを返送します。
指定したエリアやサービスが存在しない場合には、鍵バージョンとして FF FF
を返送します。
リクエストパケット
パラメータ名 | サイズ (byte) | データ | 備考 |
---|---|---|---|
コマンドコード | 1 | 02 |
|
IDm | 8 | ||
ノード数 | 1 | n | 1 <= n <= 32 |
ノードコードリスト | 2n | リトルエンディアン 鍵バージョンの取得対象のエリアコードまたはサービスコードを指定します。 システムの鍵バージョンを取得対象とする場合は FF FF を指定します。 |
レスポンスパケット
パラメータ名 | サイズ (byte) | データ | 備考 |
---|---|---|---|
レスポンスコード | 1 | 03 |
|
IDm | 8 | 対象システムの IDm | |
ノード数 | 1 | n | |
ノード鍵バージョンリスト | 2n | リトルエンディアン リストに格納される鍵バージョンはリクエストパケットで指定したノードコードリストと同じ順番で格納されます。 |
Read Without Encryption コマンド
認証を必要としないサービスからブロックデータを読み出すためのコマンドです。
Mode 0 である必要があります。
リクエストパケット
パラメータ名 | サイズ (byte) | データ | 備考 |
---|---|---|---|
コマンドコード | 1 | 06 |
|
IDm | 8 | ||
サービス数 | 1 | m | 1 <= m <= 16 |
サービスコードリスト | 2m | リトルエンディアン |
|
ブロック数 | 1 | n | |
ブロックリスト | N | 2n <= N <= 3n 前述のブロックリスト/ブロックリストエレメント参照。アクセスモードが 0 0 0 であること。 |
レスポンスパケット
パラメータ名 | サイズ (byte) | データ | 備考 |
---|---|---|---|
レスポンスコード | 1 | 07 |
|
IDm | 8 | 対象システムの IDm | |
ステータスフラグ1 | 1 | ||
ステータスフラグ2 | 1 | ||
ブロック数 | 1 | n | ステータスフラグ1が 00 の場合のみ付与されます。 |
ブロックデータ | 16n | ステータスフラグ1が 00 の場合のみ付与されます。 |
リクエストパケットの ブロックリスト とは、ブロックリストエレメントで構成され、アクセス対象となるサービス及びブロック番号を特定するために利用するデータ群です。
ブロックリストエレメントは次のような構成です。
ブロックリストエレメントが 2byte 構成の場合は、ブロック番号は 1byte です。
3byte 構成の場合は、ブロック番号は 2byte です。また、リトルエンディアンであることに注意します。
書き込み先のブロックを指定するために次のように記述をします。
※ ブロックリストには、2byte のエレメント、 2byte のエレメントを混在させることができます。
サービスコードリスト内の何番目のサービス(サービスコードリスト順番)の、何番目のブロック(ブロック番号)にアクセスする
それぞれの値の説明をします。
- 長さ
ブロックリストエレメントが 2byte であるか 3byte であるかを指定します。
値 | 意味 |
---|---|
0 |
2 byte |
1 |
3 byte |
- アクセスモード
次の値を指定することができます。
値 | 意味 |
---|---|
0 0 0 |
パースサービスへのキャッシュバックアクセス以外のブロックへの読み書きを行う場合に指定します。 |
0 0 1 |
パースサービスへのキャッシュバックアクセスを行う場合に指定します。 |
- サービスコードリスト順番
ブロックリストエレメントが対象とするサービスのサービスコードをサービスコードリスト内の順番で指定します。
サービスコードリストはコマンドにより、認識が変わります。
暗号化されていない領域への読み書きの場合、コマンド自身に含まれるサービスコードリストを意味します。
- ブロック番号
ブロックリストエレメントが対象とするブロックを指定します。
Sony: FeliCa: FeliCa カード ユーザーズマニュアル 抜粋版: 4.2.2
に詳細な例と解説があります。
次のコマンドの詳細は、FeliCa カード ユーザーズマニュアル 抜粋版 4.4
を参照すること。
- Request Response コマンド
- Write Without Encryption コマンド
- Request System Code コマンド
- Request Service v2
- Request Specification Version
- Reset Mode
別途契約が必要
次のコマンドは別途契約を締結し、開示されるドキュメントを参照する必要があります。
- Search Service Code コマンド
- Authentication1
- Authentication2
- Read
- Write
- Get System Status
- Authentication1 v2
- Authentication2 v2
- Read v2
- Write v2
- Update Random ID
まとめ
コマンド仕様を改めてみて、再確認しました。基本的に無料でできることは次のことです。
- Polling コマンドで処理権を得る
- Polling コマンドで IDm, PMm を取得する
- Request System Code コマンドでシステムコードを取得する
- Request Service コマンドでサービスコードの正当性を確認する
- 暗号化なしの読み込み
- 暗号化なしの書き込み
Suica/PASMO の規格・仕様に関しては、公開されていない上に更新もされます。
有志によってデータベース化されていたり、仕様がまとめられていたり、ライブラリが作成されていたりします。
次の要因によって、非常に調べにくい技術だなと感じました。
- NFC の仕様、FeliCa の仕様、Suica/PASMO の仕様と確認する資料が多いこと
- FeliCa の中身の管轄が Sony と フェリカネットワークス の2社が存在し、似通った仕様書が複数存在すること
- 全体的に国も絡んでいたり、専門の協議会があったりと担当部署が多いこと
- Suica の券面の仕様は見当たらなかったこと
大量の文書を書き連ねてしまいましたが、主目的であった Suica/PASMO の券面に印字された情報が NFC の機能で取得できるのか
についてはおそらく 共通領域のシステム0 を参照するべきだったのかと思います。
これについては、別途まとめます。
読み返してみたら、何を解説するでもなく仕様取りまとめて書きなぐっただけになっちゃったな・・・。
参考
- NFC/FeliCa 対応機器 開発時の注意事項
- Sony: FeliCa: FeliCa カード ユーザーズマニュアル 抜粋版
- IPA: ICカード分野セキュリティ技術
- 日本ICカードシステム利用促進協議会: 別冊
- NFC Forum: Suica Transport Case Study
- Tap into NFC: Technical Specifications
- gsuica
- IC SFCard Fan
- kikakurui: X 6319-4:2010
- Y.A.M の 雑記帳: NFCメモ
- hiro99ma blog: [felica]ブロックリストエレメントの「サービスコード順番」
- 叶鋼は午前1時に計算をする: 【Felicaを使う】Felicaリーダー・ライターとFelica Plug の通信プロトコル