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

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

> <img width="310" alt="thisisthepassword.png" src="https://qiita-image-store.s3.amazonaws.com/0/137045/167e581f-d023-4949-785a-d5d7482adae3.png">

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

> <img width="640" alt="thisisthepassword_hashed.png" src="https://qiita-image-store.s3.amazonaws.com/0/137045/fc1d36b7-cdbc-d34e-809e-808f9d42bc64.png">

# 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](https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/mac.md) に書かれている手順でインストールしてある場合は、ターミナル上で  `~/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](https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/windows.md) に書かれている手順でインストールしてある場合は、コマンドプロンプト上で `C:/Users/[YOUR_USER_NAME]/Documents/Arduino/hardware/espressif/esp32/` にcdコマンドで移動し、 `git pull origin master` することで更新することができます。

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

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

![wpa-psk-calc.gif](https://qiita-image-store.s3.amazonaws.com/0/137045/43509c79-a4b7-12f3-2676-46e5cfe05c0f.gif)

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

### [WPA key calculation: From passphrase to hex](http://jorisvr.nl/wpapsk.html)
[WPA key calculation: From passphrase to hex](http://jorisvr.nl/wpapsk.html)というツールを使ってもハッシュ化することができます。

<img width="405" alt="wpa_key_calculation.png" src="https://qiita-image-store.s3.amazonaws.com/0/137045/3d8e6988-fb43-8df7-fb29-01a2dc943560.png">

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

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

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

```JavaScript
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'))"
```

<img width="555" alt="node_js_crypto.png" src="https://qiita-image-store.s3.amazonaws.com/0/137045/32d6e025-db7f-0a9e-9ba4-568f2809d445.png">

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

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

```bash
wpa_passphrase aterm-xxxxxx-g ThisIsThePassword
```

<img width="554" alt="wpa_passphrase.png" src="https://qiita-image-store.s3.amazonaws.com/0/137045/7538e6bd-365e-e3da-d3ad-a2ed5067b076.png">

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

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

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

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