ESP32のArduinoスケッチにWi-Fiのパスワードを平文で書くのはやめよう!


ESP32用のArduinoスケッチにSSIDとパスフレーズを書いて、Wi-Fi接続をすることができますが、Arduinoスケッチの中にパスフレーズが平文のまま保存しなければならないことはRaspberry Piで無線LANのパスフレーズのハッシュ化を推奨していた身として、少し抵抗を感じることでした。

パスフレーズをハッシュ化することによって、のぞき見や悪用といったセキュリティリスクを完全ではありませんが低減することができます。

Arduino core for ESP32 WiFi chip の更新

Arduino core for ESP32 WiFi chip を 2017/12/05 以降に導入された方は、更新作業は不要です。それ以前に導入された方は、更新が必要です。

macOS

Arduino core for ESP32 WiFi chip を Installation instructions for Mac OS に書かれている手順でインストールしてある場合は、ターミナル上で ~/Documents/Arduino/hardware/espressif/esp32/ にcdコマンドで移動し、 git pull origin master することで更新することができます。

Windows

Arduino core for ESP32 WiFi chip を Steps to install Arduino ESP32 support on Windows に書かれている手順でインストールしてある場合は、コマンドプロンプト上で C:/Users/[YOUR_USER_NAME]/Documents/Arduino/hardware/espressif/esp32/ にcdコマンドで移動し、 git pull origin master することで更新することができます。

パスフレーズをハッシュ化する方法

ブラウザを利用する方法

ブラウザ内でパスフレーズをハッシュ化することができます。ブラウザ上で動作するJavaScriptのみを利用しており、ハッシュ化の計算のために外部サービスを利用していないので、外部にパスフレーズが漏れる心配はありません。

WPA-PSK calculation

私が作成したWPA-PSK calculationというツールを利用してパスフレーズをハッシュ化できます。
(このツールのリンクを、右クリック > 別名で保存で、HTMLファイルとして保存することでローカルで利用することもできます)

こちらのページにアクセスし、SSIDとPassphraseを入力し、Calculateボタンをクリックするか、Enterキーを押下すると、256bitのキーを取得できます。

WPA key calculation: From passphrase to hex

WPA key calculation: From passphrase to hexというツールを使ってもハッシュ化することができます。

こちらのページにアクセスし、Network SSIDとWPA passphraseを入力し、Calculateボタンをクリックすると、256bitのキーを取得できます。

Node.jsを利用する方法

Node.js標準モジュールのCryptoを利用して、パスフレーズをハッシュ化した256bitのキーを取得することもできます。

SSIDがaterm-xxxxxx-g, パスフレーズがThisIsThePasswordの場合、以下のスクリプトを実行することで256bitのキーを取得できます。

const crypto = require('crypto');
const key = crypto.pbkdf2Sync('ThisIsThePassword', 'aterm-xxxxxx-g', 4096, 32, 'sha1');
console.log(key.toString('hex'));

ターミナル上で実行できる形式はこちら

node -e "console.log(require('crypto').pbkdf2Sync('ThisIsThePassword','aterm-xxxxxx-g',4096,32,'sha1').toString('hex'))"

Linuxの wpa_passphrase コマンドを利用する方法

RaspbianやUbuntuといったLinux系OSに入っている wpa_passphrase コマンドを利用してパスフレーズをハッシュ化することができます。

SSIDがaterm-xxxxxx-g, パスフレーズがThisIsThePasswordの場合、以下のコマンドを実行することで256bitのキーを取得できます。

wpa_passphrase aterm-xxxxxx-g ThisIsThePassword

OSSに貢献した話

ESP32用のArduinoスケッチでは、ハッシュ化した256bit(64文字)のPSKが使えなかったので、ESP8266(持っていない)ではどうかと思い調べてみたところ、ESP8266ではこれに対応させるためのコミットが入っていることが判明しました。
esp8266/Arduino#1850

ESP8266と同じ内容の変更を espressif/arduino-esp32 にPull Requestを送ったところ、意外とすぐにマージされました。
Allow PSK instead of passphrase in WiFiSTA::begin #897

ESP32の開発で問題だと感じていたことを、自分が書いたコードとは言えないものの解決し、それが全世界の人々が使えるようになったことを嬉しく思いました。

また、以前にVue.js + webpackで作ったRaspbianの無線LAN設定ファイルを作成するツールをベースに、WPA-PSK calculationというツールを即席で作りました。Vue.jsで作ってあったおかげか、ほぼコードを削るだけで新たなツールができました。
ベースとなったツールのリポジトリで、ブランチを切って公開しています。
https://github.com/mascii/vue-wpa-supplicant-conf/tree/vue-wpa-psk-calc