仮想 MFA デバイスをオフラインバックアップする

# 今北産業

1. 仮想 MFA デバイスバックアップするには、デバイス登録時の QR コードを [VeraCrypt](https://www.veracrypt.fr/en/Home.html) かなにかの暗号化ドライブにとっておけばよくね?
2. [ZBar code reader](http://zbar.sourceforge.net/) の zbarimg で QR コードをデコードして、それをもとに [OATH Toolkit](http://www.nongnu.org/oath-toolkit/) の oathtool を起動すればスマホなくてもワンタイムパスワード生成できる。
3. QR コードを保存する際には、保存先のドライブの特性を考慮したり、サムネイルされないようにするなど、注意が必要。

# はじめに

昨今 MFA デバイスは様々なサービスのセキュリティ向上に欠かせないものとなっており、多くの人がスマートフォンを仮想 MFA デバイスとして利用しています。
一方で、仮想 MFA デバイスとして利用しているスマホを紛失したりすると色々と面倒くさいことになりがちです。

[Authy](https://authy.com/) はこの問題を解決してくれるものの、仮想 MFA デバイスにオンラインでアクセスできるようにする仕組みであり、 Authy が攻撃される可能性を考えると不安が残ります。

仮想 MFA デバイスの場合、普段はオフラインのデバイスにバックアップしておき、必要な時にリカバリできるようにしたいところです。

本稿では仮想 MFA デバイスをオフラインのデバイスにバックアップする方法を提案し、その仕組みを説明します。

# オフラインバックアップの方法

本稿で提案するオフラインバックアップの方法は以下のとおりです。

## 1. バックアップストレージの作成
まずデータをバックアップするためのストレージが必要です。
USB メモリに [VeraCrypt](https://www.veracrypt.fr/en/Home.html) などで暗号化ドライブを作成するのが手軽かと思います。

## 2. シークレットキー(登録時 QR コード)の保存
作成したバックアップストレージに、仮想 MFA デバイス登録時に使う QR コードを保存します。
以下の QR コードは [Protonmail のものです](https://protonmail.com/support/knowledge-base/two-factor-authentication/)。

![QRコードの例](https://protonmail.com/support/wp-content/uploads/2016/11/2FactorAuthSetup1-e1479248754244.png)

## 3. バックアップストレージの保管

バックアップストレージを安全な方法で保管します。

# バックアップのしくみ

仮想 MFA デバイスが使用するのは [One-time password](https://en.wikipedia.org/wiki/One-time_password) というしくみです。
これはその名の通り一度だけ使えるパスワード、ワンタイムパスワードを利用する認証方法です。

One-Time password にはいくつもの特許技術がありますが、そのうち AWS などで利用されている技術は [TOTP](https://tools.ietf.org/html/rfc6238) という規格に基づいています。

バックアップストレージに保存した QR コードには、 TOTP にもとづきワンタイムパスワードを生成するための情報が保存されています。
Authy などの仮想 MFA デバイスはその情報を利用することでワンタイムパスワードを生成しています。

# ワンタイムパスワードを生成してみる

実際に PC でワンタイムパスワードを生成してみましょう。
以下は WSL(Ubuntu) 上での手順です。 MacOS や Linux でも適宜読み替えることで同等の操作が可能だと思われます。

## 1. QR コードから情報をとりだす

まずは QR コードからワンタイムパスワード生成のための情報をとりだします。

これには [ZBar code reader](http://zbar.sourceforge.net/) の zbarimg というコマンドを利用します。

zbarimg は以下のように apt によりインストールが可能です。

```console:コンソール
$ sudo apt install zbar-tools
```

ためしに先ほどの Protonmail の QR コードから情報を取り出してみましょう。

```console:コンソール
$ zbarimg /mnt/a/MFA-Secret-QRCodes/protonmail-sample.png
QR-Code:otpauth://totp/benjerry@protonmail.com?secret=PT4NNWG7EZUAVQY44W6BH3566HHWN4DC&issuer=ProtonMail&algorithm=SHA1&digits=6&period=30
scanned 1 barcode symbols from 1 images in 0.07 seconds

```

二行目の QR-Code: で始まる行がワンタイムパスワード生成のための情報です。
これは [Google Authenticator が利用している URI フォーマット](https://github.com/google/google-authenticator/wiki/Key-Uri-Format)です。

ここからパスワード生成に必要な情報を整理すると以下のようになります。

+ ワンタイムパスワードの規格
	- TOTP
+ シークレットキー
	- PT4NNWG7EZUAVQY44W6BH3566HHWN4DC
+ アルゴリズム
	- SHA1
+ 生成桁数
	- 6
+ 生成間隔(秒)
	- 30

## 2. ワンタイムパスワードを生成する

とりだした情報を利用してワンタイムパスワードを生成するには、
[OATH Toolkit](http://www.nongnu.org/oath-toolkit/) の oathtool を利用します。

oathtool は以下のように apt からインストール可能です。

```console:コンソール
$ sudo apt install oathtool
```

oathtoll に先ほどの情報を引き渡して呼び出すと、ワンタイムパスワードが生成されます。

```console:コンソール
$ oathtool --verbose --totp=sha1 --digits=6 --time-step-size=30 --base32 PT4NNWG7EZUAVQY44W6BH3566HHWN4DC
Hex secret: 7cf8d6d8df26680ac31ce5bc13efbef1cf66f062
Base32 secret: PT4NNWG7EZUAVQY44W6BH3566HHWN4DC
Digits: 6
Window size: 0
Step size (seconds): 30
Start time: 1970-01-01 00:00:00 UTC (0)
Current time: 2018-11-29 09:58:28 UTC (1543485508)
Counter: 0x3110EAC (51449516)

078663
```

watch コマンドを使って呼び出すと、 30 秒ごとにパスワードが変わっていく様子を確認できます。

```console:コンソール
$ watch oathtool --verbose --totp=sha1 --digits=6 --time-step-size=30 --base32 PT4NNWG7EZUAVQY44W6BH3566HHWN4DC
```

# 考慮すべき点

このバックアップを行う際には、いくつかの点を考慮する必要があります。

## 1. SSD やフラッシュドライブをバックアップストレージとして利用する際には必ず暗号化する

この手法はバックアップストレージの安全性が前提となっています。
その点において必ずしも暗号化ドライブを利用する必要はありません。

しかし多くの場合で利便性から USB フラッシュドライブが選択されるでしょう。
SSD やフラッシュドライブからはファイルを完全に削除することが困難であり、
システム上削除したファイルであっても復元できる可能性があります。

そのため SSD やフラッシュドライブをバックアップストレージとして利用する際には必ず暗号化する必要があります。

## 2. ファイルシステムの画像サムネイル等、予期せぬ場所にデータが保存されないようにする

最近のファイルシステムでは画像ファイルに対して自動的にサムネイルを作成し、
ファイルとは別の場所に保存する場合が多々あります。
サムネイルとはいえ解像度によってはワンタイムパスワード生成に必要なデータを読み出せる可能性があり、
ファイルシステムの画像ファイルのサムネイルを削除し、サムネイル機能を切るなどの対策が必要です。