スマートロックをSuicaなどで解除できるものは危険なのがわかったので周知を。
— ode (@odetarou) June 9, 2019
IDmという識別子を元に認証する仕組だけど、簡単に偽造できるので
SuicaやスマホをポケットにいれておくとIDmをスキミングされてコピー可能。物理キーと違って盗まれたことに気づかれない恐怖…https://t.co/zV6kj3NInC
というわけでSuica使うの危険です。
今やスマホがあればIDmは簡単によめますし
IDm偽装も市販のリーダー(RC-S620やPaSoRi)で実装することができます。HCE(ホストカードエミュレーション)を使いリーダーにカードのふりを行わせることが可能です(下記URL参考)
Arduino+RC-S620/SでPollingに任意のIDmで応答させる | Atelier NODOKA
http://www.atelier-nodoka.net/2012/05/arduino-rcs620s-tginittarget/
NFCのセキュリティの話 - セキュリティごった煮ブログ|ネットエージェント
https://www.netagent.co.jp/study/blog/hard/20180628.html
FeliCa IDmとは? - 技術者向けNFC(FeliCa,Mifare)開発支援サイトNFC-Developer.com
http://www.orangetags.jp/words/idm
一方、ソニーは、高いセキュリティが必要とされるサービスについてはこのIDmのみに依存しないよう推奨
ちなみにAndroidでもHCE-Fという技術がありますが、IDm偽装がカジュアルにされるのを防止するためなのか02FEで始まる任意のIDmしかできずこちらは完全な偽装はできなさそうです(下記URL参考)
AndroidのHCE-Fについて調べてみたメモとサンプルソース - Qiita
https://qiita.com/gpsnmeajp/items/e525bb5c13511c18dda5
ソニーのFeliCaの現状、「HCE-F」の想定アプリケーションは? | ペイメントナビ
https://paymentnavi.com/paymentnews/62571.html
「Suicaが家カギ」な分譲マンション竣工、初のダブルロック仕様 - Engadget 日本版
https://japanese.engadget.com/jp-2020-01-14-suica.html
このマンションとかだいぶ怖そう。。2020年でもSuicaを鍵にする幻想が、、ここの場合は顔認証も併用してるからいいというさじ加減かもですが。
IDmが危険なのはわかった。じゃあIDmの代わりに何を使えばいいんだというとFelica Lite-Sが良さそうです。
Felica Lite-Sメリット
- カード(タグ)が比較的安い 200円程度
- 軽い
- 内部認証という機能を使うことでセキュアに(仕組みは後述します)
我が家では玄関の鍵をスマートロックにしたので施錠解錠の認証に使用しました。
これなら物理キーと違い無くしても個別で鍵を無効化できるのでシリンダー交換などの必要がありません。子供向けにも最適!
Felica Lite-Sの内部認証だと安全な理由
認証時に読み込むMAC値は毎回ランダムな値になるためスキミングしようとしても値が変わり意味のない値になるためセキュアになります。
認証の流れ(簡略化しています)
- カード上のファイルシステム(ブロック)にIDmと違って読み取りできない書き込み専用のカード鍵という領域があるのでそこにカード鍵をあらかじめ発行しておく。
- カード認証時にランダム値をカードに書き込む。するとカード側がランダム値とカード鍵,IDmをもとにMAC値という確認するための値を生成します(Felicaカード接触時にカード内部で処理が走り計算して出力するみたいです。すごい。)
- 認証側デバイス側でも同じくランダム値,カード鍵,IDmをもとにMAC値を生成する。カード側から読み取ったMAC値とデバイス側で生成したMAC値が一致すれば認証完了!
参考
FeliCa Liteの片側認証(Felica lite-Sより前のverのFelica liteでは内部認証ではなく片側認証と言います。理屈は一緒です)
https://sites.google.com/site/hiro99ma/nfc/experiment/card_security/half_auth
https://www.slideshare.net/hiro99ma/felica-lite
フェリカについて-02|株式会社マーケテック
https://www.marketeq.co.jp/technology/felica_2.html
詳細はFeliCa Lite-Sユーザーズマニュアルを参考(Page75)
https://www.sony.co.jp/Products/felica/business/tech-support/data/fls_usmnl_1.3.pdf
実装はPage63,64を参考に。(最終的に私もこのページ見て理解しながら実装しました)
実装編
あまり流行ってないのか最近のデバイス向けのライブラリなどは作られてはなさそうでした。
先人の方々のソースと公式仕様を参考にESP32とAndroidで実装してみました。
ESP32(Arduino)
玄関のスマートロックSesameの認証に使用するためにESP32で実装しました。
リーダーにはRC-S620Sを使用します。
https://www.switch-science.com/catalog/353/
配線などは下記URLが参考になります。
Aruduino Megaで電子工作!FeliCaリーダーで入退室記録システムを作ろう | Device Plus - デバプラ
https://deviceplus.jp/hobby/entry_f02/
サンプルコードを2つgithubに上げました。
Arduinoライブラリに対応してあるので
Libraryフォルダで
git clone git@github.com:ode1022/esp32_felica_lite.git
で利用可能になります。
使い方はサンプルを参照してください。
内部認証とカード鍵発行をするだけのサンプルプログラム
GitHub下記URL参照
https://github.com/ode1022/esp32_felica_lite/blob/master/examples/esp32_felica_lite_test/esp32_felica_lite_test.ino
リーダーに
SerialモニターのReadline入力にiと入力でカード鍵発行ができます。
内部認証してスマートロックSesameの解錠
GitHub下記URL参照
https://github.com/ode1022/esp32_felica_lite/blob/master/examples/esp32_sesame_ble_felica/esp32_sesame_ble_felica.ino
- Felica Lite-Sの内部認証にてSesameのロック、アンロックを実行
- DFPlayerMiniにて音声再生(SDカードに音声ファイル設置必要 no1:認証完了, no2:ロックします, no3:解錠します)
- ESP32の書き込みにOTAを使用(玄関までいかないでもWifi経由で書き込み可能に)
仕様部品 (価格は購入当時。目安として記載)
パーツ | 価格(¥) | 備考 |
---|---|---|
ESP32開発ボード | 490 | Wifi, Bluetooth対応マイコン。Arduino(C++)で記述できます。現在は送料が高くなってしまったので別の店で探したほうがよいかもしれません |
DFPlayerMini | 144 | SDカードにあるMP3をステレオミニジャックから再生してくれるモジュールです。3Wアンプ内蔵 |
RC-S620/S | 3666 | Felica Lite-S用のリーダー・ライター |
100均スピーカー | 110 | セリアで買いました |
Sesame Mini | 14800 | スマートロック本体 |
DFPlayerMiniの配線や使い方は下記URLが参考になります。
https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299#Tutorial
https://www.kmrweb.net/micro/dfplayer.html
Sesame用のBluetooth APIについては下記記事を参照
スマートロックのSesame miniをBluetooth連携する(ESP32編) - Qiita
https://qiita.com/odetarou/items/51424e1963c5d5099f1a
Felica Lite-Sタグを紛失した場合は別途IDmをはじく処理が必要になります。(IDmをストレージ保存で汎用化が面倒だったので今は実装されてないですが各自ハードコーディングなら簡単かと思います)
実装説明 mbed TLSでのdes
内部認証の暗号化アルゴリズムでTripleDESが必要になります。
そのためmbed TLSのdesを利用します。
des.h File Reference - API Documentation - mbed TLS (Previously PolarSSL)
https://tls.mbed.org/api/des_8h.html#a4f5bb9106306e11c906abfa46fc51b94
ESP32の標準でmbed TLSは付属していてヘッダーもあるんですが使おうとするとリファレンスエラーでコンパイルできませんでした。
調べたところDESはarduino向けのconfigでoffになっている模様
https://github.com/espressif/arduino-esp32/blob/7d7824701fe5e22f08555d3e1ce3180a922b2151/tools/sdk/sdkconfig#L679
CONFIG_MBEDTLS_DES_C=
上記が空でなくyになっていないと利用できなさそうで。
そのためヘッダーファイルはありますが
https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/include/mbedtls/mbedtls/des.h
コンパイル済みの下記ライブラリファイルにDESが含まれないため使えないのだと思われます。
https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/lib/libmbedtls.a
対応策としてmbed TLSのHPからDESのソースだけ落として使用しました。
Android(Kotlin)
Androidでカード鍵発行を行うためのアプリも作成しました。
これでわざわざ玄関までいかないでスマホで気軽に発行できます。
下記にてソースとAPKがダウンロードできます
https://github.com/ode1022/android_felica_lite_tool
FeliCa Lite-Sのカード鍵発行をAndroidでできるようにするやつ作った(内部認証用)
— ode (@odetarou) May 6, 2020
これで玄関のリーダーまで行かないでもスマートロックのSesame開ける鍵発行が簡単に。 pic.twitter.com/u7WKExxBv7
Felica自体のアクセスは下記URLを参考にしました。Android標準ライブラリではreadWithoutEncryptionすらもないため自作するのがつらい。。iOSにはあるのに。
AndroidでFelica Liteを簡単に読み書きするライブラリ - Qiita
https://qiita.com/gpsnmeajp/items/a3717b9995f7061f19ca
Kotlin初めて書いてみましたがJavaに比べてやっぱりいいですね。
上記アイコンは下記サイトにて無料で作れました。
https://www.logofactoryweb.com/
その他実装見つけたもの
Go,Pasori
Go製 Felica ライブラリ pasori に MAC付きRead とMAC付きWriteを足した - bamch0h’s diary
https://bamch0h.hatenablog.com/entry/2019/03/22/231958
Visual C++, PaSoRi
LazyPCSCFelicalite.h - Seg's Homepage
https://sabowl.sakura.ne.jp/gpsnmeajp/cpp/lazypcscfelicalite/
Ruby,Pasori, Windows
https://tipszone.jp/20140902_introduction-to-nfc/
個別化カード鍵の作成ロジックの検証の際に試したのですが、個別化カード鍵の作成部分で意図しない動作の箇所があるようでした。
意図しない動作と思われる箇所
# 下記行の修正が必要そうでした。l[0][7]だと常にnilになるため
# k1[7] ^= "\x1B" if l[0][7] == 1
k1[7] ^= "\x1B" if l[0].unpack('B*').first[7].to_i == 1
C++,ラズパイ,RC-S620/S
https://github.com/easter2501/felica_readwrite
C++で書かれていたのでESP32移植の際に参考にさせていただきました。ありがとうございます。
個別化カード鍵の作成ロジックでは意図しない動作の箇所があるようでした。
意図しない動作と思われる箇所
1. 下記で()をつけないと優先順位が違くなる。
//msb = (K1[i] & 0x80 != 0)? true : false;
msb = ((K1[i] & 0x80) != 0) ? true : false;
2. 下記は0x01になる。
//下のバイトからのcarry
//K1[i] = K1[i] | 0x0l;
K1[i] = K1[i] | 0x01;
3. input_key3がdes計算に使われていない
個別化カード鍵の作成
個別化カード鍵の作成のロジックはSonyのリファレンス実装と違っていても問題はないので互換性に注意が必要そうでした。
参考にした先人の方々のコードでも2言語(C言語, Ruby)の実装確認していて間違いがあるのを発見しました。
Sonyの仕様書を確認したのと、2言語(C言語, Kotlin)で実装して一致するのを確認したので恐らくあっているかと思うのですが
実装ミスあれば指摘お願いします。
(私はKotlin版実装時に一致しないのでC言語版のバグに気づきました。。)
カード発行の内容
私の書いたコードですとカード鍵(カードごとの固有キー)の設定のみで
正式な1次発行、2次発行はしていません。
行うとカード鍵の書き換えができなくなるので。。
悪意ある人にタグ内の鍵を書き換えられる可能性が考えられますが鍵が壊されるだけで盗まれるわけではないので良しと考えています。
それよりもバグなど出た際に書き換えできないほうが痛いなぁーと。。
必要があればカード鍵を書き換えられないようにできます。MCブロックを設定し1次発行することで可能です。
FeliCa Lite-S スターターマニュアルより(16,17ページ)
https://www.sony.co.jp/Products/felica/business/tech-support/data/fls_starter_manual_1.11.pdf
1 次発行では、「システムブロックの設定」を行います。設定を変更不可にするためには、MC[2]に 00h を書き込んだ後に電源を切ります。この後に MC[2]を FFh に戻すことはできません。
カード鍵: ブロック135番(0x87番=CKブロック)
参考:hiro99ma blog: [felica]FeliCa Liteの1次発行と2次発行
https://hiro99ma.blogspot.com/2011/08/felicafelica-lite.html
Felica Lite-Sのタグとケース
ダイソーで買った100円の入れ物にシールタイプのFelica Lite-Sタグを入れるのがコンパクトで良かったです。
Felica Lite-Sでシール型の小さいやつを購入
— ode (@odetarou) June 25, 2019
これなら子供のランドセルのベルトに貼ってスマートロック解錠しやすいかも
盗難されても個別IDで無効できるのが物理キーと違って強みhttps://t.co/3Pp39dpjl2
光当てるとスケスケ!
円形の一番小さそうなやつは売れ切れで残念https://t.co/T4MzAdZwaN pic.twitter.com/eKzeRKZmZI
スマートロックの鍵になるFeliCa Lite-Sの小型チップは100円で丁度いい入れ物が!
— ode (@odetarou) July 7, 2019
子供のランドセルに伸びる紐と組み合わせていい感じになりました。
デコってかわいくなってる😁
自分用は簡素に。
チップは260円で買えるし持ってるバッグ全部につけてもいい気がしてきた。 pic.twitter.com/RlmnERFxTu
カードタイプ
Amazon | 【10枚】フェリカカード FeliCa Lite-S フェリカ ライトS ビジネス(業務、e-TAX)用 白無地 【安心の1年品質保証】RC-S966 FeliCa PVC Card | フェリカカード | ネットワークカード 通販
https://www.amazon.co.jp/dp/B077KQ1FZ8
10枚で1,810円 1枚あたり181円
Amazon | おためし5枚セット フェリカカード FeliCa Lite-S フェリカ ライトS ビジネス(業務、e-TAX)用 白無地 【安心の1年品質保証】RC-S966 FeliCa PVC Card | フェリカカード | ネットワークカード 通販
https://www.amazon.co.jp/dp/B077KHP8JB
5枚で945円 1枚あたり 189円
シールタイプ
Amazon | Fes-001【5枚】フェリカ ICシール 売れてる理由は【 防水&防塵対応】 【既存の社員証/学生証/入館証などに貼りつけると ICカードに早変わり!】 業務/e-TAX用 FeliCa Lite-S RC-S966 フェリカシール | M-ACS(マクス) | ネットワークカード 通販
https://www.amazon.co.jp/dp/B085WQL5NC
5枚で1300円 1枚あたり260円
42*26.5mm
小さくて安いので私はこれを購入しました。
Amazon | FeliCaシール耐衝撃耐水ICシール(felica lite-s・フェリカライトS)ラベル5枚セット | FeliCaシール | インターフェースカード 通販
https://www.amazon.co.jp/dp/B07N2GQTLR
5枚1490円 1枚あたり298円
34x54mm
Amazon | FeliCa フェリカ ラベルシール型 nfcタグ Lite - S (フェリカラベル ライトS )ICタグ 業務用 e-TAX PaSoRi iPhone等のiOS機器用 (5枚) | Fongwah | メモリースティック 通販
https://www.amazon.co.jp/dp/B079DL9F74
5枚1410円 1枚あたり282円
50x40mm
Amazon | フェリカ ラベルシール型 ICタグ (FeliCa Lite-S, フェリカライトエス) NFC Forum Type3 Tag 業務用, TS-L2-NFC | オレンジタグス | パソコン・周辺機器 通販
https://www.amazon.co.jp/dp/B00G8SHKIS
丸型 直径27mmで一番小さい!
あまり売ってない
価格が513円と高い
yahooでも売っているが330円+送料が840円とより高くなる。
オレンジタグス(業務用) NFC Forum Type3 Tag フェリカラベルシール型非接触ICタグ長方形φ27mm(白) FeliCa Lite-S (管理用シリアルPSID番号入り) TS-L2 :TS-L2:オレンジタグスダイレクトYahoo!店 - 通販 - Yahoo!ショッピング
https://store.shopping.yahoo.co.jp/nfc-card-felica/ts-l2.html
スマホをカード扱いにして認証する場合
Androidに搭載されているFelicaのIDmを読ませるのは危険なので変わりにAndroid上のHCE-F(ホストカードエミュレーションFelica Ver)にて実装するのがよさそうですが
調べてみるとバックグラウンドではHCE-Fは実行できないのでアプリを起動しないといけないみたいです。。これならSesameなどのアプリ立ち上げるのと変わらなくなっちゃいますよね。。
別案としてはMifareなどのType-A系でのHCEではバックグラウンド実行可能みたいなので
リーダー側と、Androidアプリ(HCE)側の両方でオレオレ認証プロトコル実装すればなんとかなるようなきがします(大変そうですが)
他のNFC系の規格(Mifareなど)はどうなの?
FeliCa Standard
Suica等の電子マネー等に使われているやつですね。
暗号領域やプライベート領域と呼ばれている場所のアクセスには別途契約が必要でランニングコストもかかるため一般利用は難しそうです。
よくあるスマホでSuicaの残高確認などのアプリは共通領域(フリー領域)と呼ばれている場所に書かれているる改ざんされても大丈夫なコピーデータ的なデータ部分を読み込んでいます。
Mifare
海外で主流NFCのMifareは安くてReadにパスワードかけれるので良いかと思ったら
http://dsas.blog.klab.org/archives/2017-12/52286711.html
一般ユーザーが使えるレベルのMifareカードは脆弱性があるらしいです。。
複数種類あるのでまとめると
脆弱性あり
- Mifare Classic
- Mifare Ultra Light
- Mifare Desfire
脆弱性なし
- Mifare Desfire EV1
- Mifare Plus(AES)
ただし脆弱性なしのタイプは仕様が公開されていなくNDAが必要なためライブラリも情報が少なそうです。。
そもそも日本で脆弱性なしのタイプのカードを買うのが難しそうでした。。
というわけでFelica Lite-Sがよさそうという結論に。
どうしてもやるなら下記がMIFARE Desfire EV1に対応しているライブラリのようなので試すといいかもしれません。
nfc-tools/libfreefare: A convenience API for NFC cards manipulations on top of libnfc.
https://github.com/nfc-tools/libfreefare
Mifare脆弱性について
脆弱性について興味深かったので調べた情報をまとめておきます。
https://smartlockpicking.com/slides/Confidence_A_2018_Practical_Guide_To_Hacking_RFID_NFC.pdf
海外の記事ですがかっこいいパスワードハックの仕方がまとめられていました。興味深い内容なのでおすすめです。図もあってなんとか読めました。
1キーでもわかればハックできる方法と、キー全くわからなくてもハックできる方法どちらも紹介しています。
特に Chameleon Mini reader attack はいいですね。
リーダーに対してカードのふりする偽装端末を使うことでパスワードを教えてもらえるテクニック!
DIY electronic RFID Door Lock with Battery Backup - CodeProject
https://www.codeproject.com/Articles/1096861/DIY-electronic-RFID-Door-Lock-with-Battery-Backup
こちらも英語記事ですがスマートロックに使うためにセキュリティー周りのこと書かれています。
第1世代のDesfireカードはサイドチャネル攻撃で脆弱性がある。
2009年登場のDesfire EV1カードは安全らしいです。
この人は公開されてないがなんとかEV1対応のコード苦労して対応したそうです。
下記はMifareの脆弱性を利用して攻撃したり、リカバーするためのツール。MifareClassicはだめだこりゃ。
ikarus23/MifareClassicTool: An Android NFC app for reading, writing, analyzing, etc. MIFARE Classic RFID tags. https://github.com/ikarus23/MifareClassicTool
nfc-tools/mfoc: Mifare Classic Offline Cracker
https://github.com/nfc-tools/mfoc
nfc-tools/mfcuk: MiFare Classic Universal toolKit (MFCUK)
https://github.com/nfc-tools/mfcuk
番外編 iPhoneのIDm
iPhone持ってないので検証してはないですが
Suica以外のウォレット系のIDmの場合は端末のロック解除後でないと反応しないらしいので通常のカードのIDmよりはスキミングされにくいかもしれません。
ホームボタン(ない場合は電源ボタン)を2度クリックしないと反応しない仕様になっていますね(IDmも返さないです)
— べあ (@beahshy) September 4, 2019
Suicaだけシステムコードが0x0003指定でポーリングすればスキップできるのでスキミング出来てしまいますが、その時は反応があります
FeliCaのPollingによるApplePayのWalletの動作 - Qiita
https://qiita.com/bellx2/items/fb081c4bdd822c8d36fd
WalletでTouchID認証後にそのカードに対する応答が有効になりカードのIDmや情報が返る。
iPhoneのFeliCa、どうもHCEくさい。 iDとQUICpayでIDm比較したら製造者コードが違う。
— ふー (@foo87b) December 14, 2016
なるほど、カードエミュレーションによる実装なのでソフト側で動的に処理できるのでロック解除と連携できるってことみたいですね。(HCEは処理遅いからSuicaには厳しいという記事も読んだ記憶もあるのだけどAppleと組んでどうにかなったのかな?)
軽くググってもHCEで実装されているという記事は見つからなかったですが参考までに。
Felica Lite-Sの認証以外の用途
FeliCa Lite-S スターターマニュアルに使用例が詳しくのっているので参考になります(18ページ以降)
https://www.sony.co.jp/Products/felica/business/tech-support/data/fls_starter_manual_1.11.pdf
資料
Sonyの公式資料。めちゃくちゃ詳細に仕様書いてあります。情報量多くて最初うってなりますが正確に把握できます。
https://www.sony.co.jp/Products/felica/business/tech-support/
私もここらへんの資料読みながら実装しました。
ここ最近はスマートロックのためにNFC調査してて、Felica Lite-Sに活路を見出して進め中
— ode (@odetarou) June 9, 2019
ESP32で動くライブラリとかあるっしょーって探したら皆無なの…
他実装のソースと公式Doc見ながらTriple-DESとか知識吸収中
大体わかってきて楽しいよー (涙)https://t.co/LryxKFS8xmhttps://t.co/WUsZxtE79q pic.twitter.com/1pJbWJ4Tpj