Python

【Python】PaSoRiによるICカードの読み取り

投稿日:2019年8月13日 更新日:

目的

交通機関などで使われるようなICカードの中身をpythonを使って自宅で閲覧するための検証をします。
とりあえず、読み取るだけまでを目指し、なるべくシンプルなコードで試そうと思います。

環境

  • Windows10 64bit
  • python3.7(Anaconda3)
  • PaSoRi(RC-S380)

方針

pythonにはnfcpyというnfcデバイスの制御ができる、素晴らしいライブラリがあります。今回はこのnfcpyを使用します。

以下のnfcpyの説明サイトで詳しく書かれていますので、これを参考に進めたいと思います。
https://nfcpy.readthedocs.io/en/latest/topics/get-started.html

簡単に言うと、次のような順番で実施します。

  1. Zadigというツールを使いWinUSBをインストールする。
  2. libusbをインストールする。
  3. pythonでコーディングする。

WinUSBとはMicrosoftが提供するUSBドライバらしく、おそらく、PaSoRiなどのリーダのIO制御に必要なのかと思います。そして、ZadigはそのWinUSBを簡単にインストールできるGUIベースのツールのようです。
libusbはUSBデバイスへアクセスするためのCのライブラリで、おそらくnfcpyを使う前提として必要なのだと思います。

ということで、まずはWinUSBとlibusbを準備した上で、pythonのnfcpyを使ってコーディングをしていきたいと思います。

Step1 : WinUSBのインストール

以下のZadigのサイトからZadigの最新版をダウンロードします。今回はzadig-2.4をダウンロードしました。
https://zadig.akeo.ie

zadig-2.4.exeをダウンロードして任意の場所に保存した後、右クリック から 管理者として実行を選択します。

すると、GUIが開くので、以下のようにOptions > List All Devicesにチェックを入れます。

次に、PCのUSB端子にPaSoRi(RC-S380)を接続し、下図のようにプルダウンメニューからNFC Port/PaSoRi 100 USBを選択します。

そして、Driverのところで、WinUSB(v6.1.7600.16385)を選択し、Install Driverをボタンを押します。下図は一旦インストールした際に撮ったスクショのため、Reinstall Driverになってますが、初回はInstall Driverになっているはずです。

Install Driverをクリックすると、インストールが始まりますので、完了するまで待ちます。以上でWinUSBのインストールは完了です。

Step2 : libusbのインストール

以下のサイトからlibusbをダウンロードします。ページのDownloads > Lates Windows Binariesを選択すると、ダウンロードが開始され、7zの拡張子の圧縮ファイルが落ちてきます。
https://libusb.info/


ダウンロードしたファイルを任意の場所へ保存したら、7zipを使って解凍します。なお、7zipをPCにインストールしていない場合は以下から入手できます。

https://www.7-zip.org/download.html

解凍して生成されたフォルダの中から以下の2つのファイルを指定の場所にコピーします。この作業を忘れるとPaSoRiは動きませんので、注意してください。

  1. MS64dll\libusb-1.0.dllを C:\Windows\System32 へコピーする。
  2. MS32\dll\libusb-1.0.dll を C:\Windows\SysWOW64 へコピーする。

以上でlibusbのインストールは完了です。

Step3 : Pythonによる実装

まず、Anaconda promptを立ち上げてnfcpyをインストールします。

$ pip install nfcpy

次に、PaSoRiの上にICカードを載せます。

そして、以下のコードを実行します。

import nfc

#接続定義
clf = nfc.ContactlessFrontend('usb')
print(clf)

#タグの取得
tag = clf.connect(rdwr={'on-connect': lambda tag: False})

#結果表示
print(tag)
print(dir(tag))
#====Result===========
SONY RC-S380/P on usb:002:001
Type3Tag 'FeliCa Standard (RC-S???)' ID=xxxxxx PMM=xxxxxx SYS=xxxxxx
['IC_CODE_MAP', 'NDEF', 'TYPE', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_authenticated', '_clf', '_format', '_is_present', '_ndef', '_nfcid', '_product', '_target', 'authenticate', 'clf', 'dump', 'dump_service', 'format', 'identifier', 'idm', 'is_authenticated', 'is_present', 'ndef', 'pmm', 'polling', 'product', 'protect', 'read_from_ndef_service', 'read_without_encryption', 'request_response', 'request_service', 'request_system_code', 'search_service_code', 'send_cmd_recv_rsp', 'sys', 'target', 'type', 'write_to_ndef_service', 'write_without_encryption']

ICに用意されているタグが簡単にわかりました。
あとは、tag.dumpすると、実際のデータを見ることができます。(途中割愛しています)

tag.dump()
#---Result
'System 0003 (Suica)',
 'Area 00

 '    Cyclic Service 36: write with key & read w/o key...,
 '     0000: 16 01 00 ...

 |........D.......|',

データを見ることはできましたが、データの意味まで理解するためには、そもそもどんな形でデータが入っているかの予備知識があったり、暗号化されていないことが前提となりそうです。

結果

python nfcpyを使うと、初心者でもデータの中身まで簡単に表示できました。
ただし、中身の意味を知ろうとした場合はICカードがどう運用されているのかの予備知識も必要そう。平文ベタ打ちなら何かしらはわかるかも。

以上

-Python

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

CentOSからAnacondaアンインストール

Contents1 目的2 Step1 : .pyenvの削除3 Step2 : bash_profileのpathの削除4 Step3 : .condaの削除5 Step4 : 確認 目的 以下の記 …

【Python】K-NNによる分類モデル

Contents1 概要2 データ3 ソースコード4 勉強になったこと 概要 機械学習のコードのお勉強のためPythonのscikit-learnのK-NNを使用して分類問題をやってみます。 データ …

Python datetimeの基本的な使い方

Contents1 目的2 基本メソッド2.1 今日の取得2.2 年月日の取り出し2.3 明日の取得2.4 現在日時の取得3 現在時、分、秒、マイクロ秒の取り出し3.1 ISOフォーマットへの変換 目 …

【Python】四分位数の計算

Contents1 目的2 データ準備3 四分位数4 四分位偏差5 注意点 目的 これまで、データの平均の考え方とその計算方法について学びました。しかし、データの特性の評価には平均だけでなく、ばらつき …

【Python】標準変化量と変異係数計算

Contents1 目的2 データの「まれ」さ3 標準変化量4 Pythonによる標準変化量の計算5 変異係数 目的 以前にデータの分散度を測る標準偏差という指標についてpythonで求めてみました。 …

言語切り替え

カテゴリー