お知らせ

(本サイトは、アフィリエイト広告を利用しています)

SwitchBot スマートロック を BLE APIで開閉 ネットがなくても制御できる(noble/NodeJS)

2024年8月14日IoT・スマートホーム

以前の記事で、Web APIを使ってSwitchBotスマートロックを開閉しました。

Web APIはインターネット接続が必要になります。 一方、 近距離無線のBluetooth BLE を使えば、近くにあるスマートロックは、インターネット接続がなくとも開閉でるきるはず。

幸いなことに筆者の推しであるSwitchBotは Web AP 仕様に加え、Bluetooth API仕様も公開されています。

この点が筆者がSwitchBot 推しである最大の理由でもあるのですが、問題はSwitchBotのBluetooth APIは文書化されていないプロトコルが存在することです。 特に、スマートロックの BLEプロトコルに関しては、 以下の仕様書を読んでも、ロック開閉のためのプロトコルが書かれていません。

前回の記事では、インターネット上の情報源を整理しました。

この記事で述べたように、文書化されていないプロトコルに関してもgithubでソースコードが公開されているようなのです。

そこで今回の記事では、 文書化されてないソースコードをもとに、SwitchBotスマートロックをWeb APIを使わずにBluetoothだけで開閉してみます。

SwitchBotスマートロック製品は 指紋認証 ができるタッチキーと言う製品もあり、これを使うとネットを使わずにスマートロックを操作できます。これと同様のことを自作のプログラムから行うイメージです。

SwitchBotスマートロックのBLEプロトコルは暗号化されている

当初、筆者はSwitchBotが公式に公開しているBLE APIのプロトコル仕様の中に、スマートロックのプロトコルがないので、仕様は非公開なのだと考えました。

しかし、ネット上をいろいろ調べてみると、node-switchbotと言う Javascriptを使ったライブラリがBLEを使ったスマートロックの制御を実装していることを見つけたのです。

このソースコードを読むと、公開されているBLE APIの仕様書の中には存在しない方法により、暗号通信していることがわかります。

その情報ソースに関しては、前回の記事でまとめておりますので、そちらも併せてご覧ください。

ここで実装されているプロトコルを利用すれば、自前でBluetoothの通信によりスマートロックを開閉するプログラムができるはずです。

暗号化の仕組みについて

ここでは、 筆者がソースコードを解析して理解した、スマートロックの BLEプロトコルにおける暗号の仕組みを説明します。

暗号化は2段階の作業が必要になります。

  • SwitchBotのアカウントからキーIDを取得する
  • キーIDを使ってBLEコマンドを暗号化する

それぞれ説明します。

SwitchBotのアカウントからキーIDを取得する

最初の作業工程は、クラウドサービスを利用して、SwitchBotのアカウントからキーIDを取得することです。

pySwitchBotと言うオープンソースのPythonのプログラムの中にAPIを呼び出すコードがありました。

ここで使われるクラウドのWeb APIも筆者が探した限り、どこにも文書化された仕様書はありませんでした。しかし、pySwitchBotのスクリプトを使うと、キーIDとエンクリプションキーと呼ばれる2つの情報を入手することができるのです。実行時は、ユーザIDとパスワード、及び制御したいスマートロックのMACアドレスが必要になります。つまり、これは、ユーザ情報を元に、そのユーザが登録している(使用している)スマートロックの認証情報が取得できるスクリプト、というわけです。

筆者はpySwitchBotを解析し、キーIDとエンクリプションキーを取得する部分だけ、試しにJavaScriptのプログラムにしてみました。スマートロックを解除するためのIDを取得するプログラムをnpmのパッケージとして公開しました。以下のリンクから利用することができます。npmの使い方に慣れている方にはこちらの方が便利でしょう。

キーIDを使ってBLEコマンドを暗号化する

スマートロックと通信するためには、上で得られたキーIDとエンクリプションキーが必要になります。

SwitchBot スマートロックと自前で実装するBLE セントラルの間のシーケンスは、以下の図のようになります。

上の図はシーケンスの全体像ですが、特に赤枠の中を見てください。

赤枠の中の最初の呼び出しは、キーIDを暗号化せずにスマートロックに送り、IVと言う値を得るものです。 IVはイニシャルベクトルと呼ばれ、 暗号をより強固にする仕組みの1つです。

次に、このイニシャルベクトルを使って、 解錠または施錠を行うBLEコマンドを暗号化します。

暗号アルゴリズムは、AES 128ビットCTR モードと言うものを使っているようです。

このフローは後ほど説明するnode-switchbot のライブラリの中で実装されているものです。筆者はこのBLEプロトコルをEPS 32プラットフォームの上で使うことを考えており、ライブラリのソースコードを解析しています。

解析結果として得られるプロトコルの詳細については別の記事でお届けする予定です。お楽しみに!

スマートロックを BLE 制御する ソースコード

今回は、上述のJavaScriptライブラリーであるnode-switchbot を使い、クラウドから得られたキーIDとエンクリプションキーが正しく使えるものなのか、検証してみることにしました。

確認したのはMacOSです。node-switchbot はnobleというBLE 通信のためのパッケージに依存していますので、適切にインストールしておく必要があります。

node-switchbot を使ったコードは以下のようなものです。

このプログラムでは、最初にSwitchBotオブジェクトを作成し、そのインスタンスのdiscover()と言う関数を実行します(22行目)。 discovery()の引数には操作したいスマートロックのMACアドレスを指定します。MACアドレスは上でキーIDとエンクリプションキーを取得したときに使ったものと同様です。期待するデバイスが見つかると、それを示すオブジェクトが返ってきます。

オブジェクトには setKey()と言う関数があるので、 解錠・施錠のための関数を呼び出す前に、上で得られたキーIDとエンクリプションキーをセットします(29行目)。

後はlock()かunlock()か、好きなほうの操作を行えば良いわけです(30行目)。

筆者の手元では、MacOS上でこのプログラムは動作しました。つまり、インターネット経由ではなく、Bluetoothを使ってMacのコマンドLINEからスマートロックの施錠解除ができました。

今後について

この記事では、SwitchボットスマートロックをDLのBluetooth energyのプロトコルを使って自前のプログラムから解錠、または施錠ができるかどうか確認しました。

非公開のWeb APIを使って、暗号化のためのキーIDとエンクリプションツーを入手すれば、 自前のプログラムからスマートロックを制御することができました。 使用したのはnode-switchbot と言う JavaScript のライブラリです。

オープンソースのJavaScriptの実装が動作することがわかったので、今後はこのプログラムをで使われているBLEコマンドを解析しESP32の実装に移植して行きます。 そのうち記事にしますので、お楽しみに!

メールマガジンにて本サイト(Tech Landlordテック大家さん)の更新情報をご連絡します。
本サイトのプライバシーポリシーをご確認の上、是非メールアドレスをご登録下さい!


プロフィール

テック大家さん
ソフトエンジニア兼不動産オーナー。
某超有名日本メーカーにおいてソフトウエア開発畑を30年近く勤務。
かつてはWindowsのアプリ開発や、組み込み機器のソフト開発を行う。プロジェクトマネジメント・オフショア開発・要件管理などの経験あり。現在は、個人開発で、JavaScript/TypeScript/React/Express、PHP/Laravel、Firebase、Google cloud、Arduino(C++)などでプログラミングを楽しむ。
サラリーマンの傍ら不動産経営を始め、現在、1棟モノの賃貸4物件を東京・神奈川に所有。夫婦でおよそ20年の賃貸経営の実績。
最近の物件では、入居者向けフリーWiFiなど、テック系の設備はDIYで自ら構築。
海外MBA取得。