ジャパンネット銀行のカード型TOTPトークンが届いた

日記。

ジャパンネット銀行はプロプライエタリなRSA SecurIDからOATH(OAuthではない)のTOTPベースのトークンに切り替えている。というわけで、手元のRSA SecurIDが期限切れになるのに合わせて、新しいカード型のトークンが届いた。

# かっこいい

![cap1.gif](https://qiita-image-store.s3.amazonaws.com/0/67446/c73aa931-7e17-6aa0-73de-4c5683c71f26.gif)

※ 他人にワンタイムパスワードを見せるのはあんまり良いことでは無い(後述)

新しいカード型トークンはGemaltoのEzioシリーズ ( https://www.gemalto.com/brochures-site/download-site/Documents/eba_ezio_oncard.pdf ) で、クレジットカードサイズの本体に、電子ペーパーディスプレイ、バッテリ、押しボタンを内蔵している。

Ezioは **TOTP** (Time-based OTP - トークンに時計が内蔵されていて、時刻を鍵に使うもの、HOTPの変種)と **HOTP** (HMAC-based OTP - トークンに不揮発メモリが内蔵されていて、トークンの出力回数を鍵に使うもの)の2種をサポートしている。↑の動画で解るように、ジャパンネット銀行ではTOTPを採用しているようだ -- 一度表示を消しても、直ぐにボタンを押せば同じ数字が再度表示される。

表面の "ワンタイムパスワードを他人に言ってはいけません" はシールで追加されていて、昨今のワンタイムパスワードの認知度の向上に伴って電話口でワンタイムパスワードもついでに聞き出す手口が出てきたことに対応したものだろう。

# 従来のSecurID

従来、ジャパンネット銀行はRSA SecurID SID700モデル( http://www.techmatrix.co.jp/product/securid/token/sid700.html )を採用していた。これはRSAによるプロプライエタリなアルゴリズムを採用しているものの、出てくる数字が10進6ケタなのは同様。

# 導入の背景

導入の背景はインタビューに語られている。

- https://www.paymentnavi.com/paymentnews/64756.html
 - 日本の銀行初、薄さ0.8ミリのカード型トークンを口座保有者全員に配布へ

ちょっと意外なのはRSA SecurIDよりも高いコストに言及している点で、

> 現状、コストについてはキーホルダー型よりもカード型の方が高く、「希望の価格には到達しませんでした」と小谷氏は苦笑いするが、カード型では「薄型の封筒でキャッシュカードと同梱が可能になった点やシステム化などで郵便代や事務コストが削減できた。単年的にみるとトータルコストは増えるが、お客さまの利便性向上や今後の商品設計を考えると期待できるサービスになる」と笑顔を見せる。

どこがコスト要因になっているのか微妙に気になるところではある。薄型化のために電子ペーパーを採用したことだろうか。。

ボタンによるOn/Offを顧客要望としているが、電子ペーパーは書き換えの電力コストがそれなりにあるのと、(おそらく)トークンの使用頻度が十分に低く、電池の延命を狙ったものではないかと思う。

ちなみにSecurIDではトークンに有効期限が設定されていたが、今回のカード型トークンには無い。

# 他人に数字を見せるのは安全なのか

まず、 **トークンがTOTPであることを事前に確認している** 。もし、トークンがイベントベースのHOTPであった場合、攻撃者はぼくの口座の口座番号、パスワードを持って、↑の動画にあるOTP "630238" をジャパンネット銀行のホームページに入れたら口座にログインできてしまう。HOTPのワンタイムパスワードは実際に使われない限り無効にならないため、この "630238" を使って口座にログインするのは早い者勝ちになる。

もちろん、TOTPトークンであっても、ワンタイムパスワードが発行されてからある程度の期間は有効となっているため、動画の撮影を十分に昔に済ませておく必要がある。

というわけで、今回の記事にトークンの画像を載せるために、

1. トークンの品種を調べ
2. トークンが時刻ベースのワンタイムパスワードであることを確認し、
3. 記事にはN週間前の動画を載せる

という自衛策を取っている。(良い子のみんなは、こんな危いことをわざわざやらずに撮影用のトークンを用意すべきだろう。ジャパンネット銀行の場合、追加のトークンは約1000円で発行できる。)

残念ながら、この N週間 にどの程度期間を置けば良いのかは良い基準が無い。つまり、トークンが出力したワンタイムパスワードの有効期限は認証側で自由に設定できるため、実は銀行が1ヶ月前とかのワンタイムパスワードを受け入れるように何らかの間違いで設定している可能性も否定できない。というわけで、他人にワンタイムパスワードを見せても良いと確信するにはちょっと弱いと言える。

RFCでは、 [通常のワンタイムパスワードの有効期限を30秒](https://tools.ietf.org/html/rfc6238#section-5.2)、[時刻のズレを考慮したre-synchronization windowとして前後1つづつ](https://tools.ietf.org/html/rfc6238#section-6) - つまり30 x 3 = 90秒間を想定している。↑の動画に載っているワンタイムパスワードは当然取得されてから90秒以上経っているため、何の役にも立たないと期待できる。

```:rfc6238#section-5.2
   We RECOMMEND a default time-step size of 30 seconds.  This default
   value of 30 seconds is selected as a balance between security and
   usability.
```

```:rfc6238#section-6
   This would mean the validator could perform a validation against the
   current time and then two further validations for each backward step
   (for a total of 3 validations).  
```

timestempの30秒はRECOMMENDレベルで推奨されているが、resynchronization windowの巾は特に推奨は無いようだ。

## 有効期限の切れたOTPは本当に無価値か？

次のポイントは、有効期限の切れたワンタイムパスワードが、本当にセキュリティ上の脅威にならないか？というポイントだろう。

いまのところ、TOTPはHMAC-SHA1を時刻に対して適用し、それを31bitに縮退した上で下位10進6桁を取ることでワンタイムパスワードを生成している。このワンタイムパスワードが乱数と十分に同等であれば、つまり、個々のワンタイムパスワードに関連が無ければ、有効期限の切れたワンタイムパスワードの画像を載せていても安全と言える。

TOTPの元になっているHOTPのRFCでは、プロトコルの安全性を2段階で説明している:

1. HMAC-SHA1 が安全である
2. HMACによって得られたコードを端折っても安全である

HMAC-SHA1の安全性は今のところ広く信じられているため、HOTPのRFCでは単に前提としている。[後者はHMAC-SHA1の代わりに、乱数表を使った"理想的なOTP"関数であるHOTP-IDEALを仮定](https://tools.ietf.org/html/rfc4226#appendix-A.2)し、桁数の縮退によって、出力される数値の偏りが無視できる程度であるとしている。

これらが正しいとすると、今後画期的な発見が無い限り、動画に出した"630238"からHMAC-SHA1の鍵を当てるためには、brute forceするしかない。つまり:

- 2<sup>160</sup> の鍵候補から動画の撮影時刻付近に"630238"を出力するであろう鍵 2<sup>160</sup> / 10<sup>6</sup> = **1.4615016 x 10<sup>42</sup>** 個

(実際には、ジャパンネット銀行のトークンがHMAC-SHA1を使っている証拠はどこにもない。なので、もっと弱いアルゴリズムを使っている可能性もあるし、SHA2のようなより長いハッシュアルゴリズムを使っている可能性も否定できない。)

を1つ1つ試さないといけない。当然、動画の撮影時刻を適当な精度で予測する必要があり、また、鍵候補を絞り込むのにもbrute forceが必要なため更に困難と言える。こんなことをするなら、次のワンタイムパスワードが "123456" になる可能性(1/10<sup>6</sup> = 1/100万)に賭けたほうがずっとマシということになる。