狐の王国

人は誰でも心に王国を持っている。

パスワード認証はもはや過去の遺物にするべき

『完全にお前たちに責任がある』JALマイレージ不正アクセス判明に高木浩光先生が憤激という記事。
JALの顧客向けサイトの認証が数字のIDと数字のパスワードだけで案の定不正アクセスを許し、顧客のマイレージポイントが盗まれた事件についての話なのだが、憤激もうなずける内容ではある。

今後金融関係のウェブサービスが拡充していく流れはすでに米国などでも始まっており、こうした認証に関わるセキュリティ問題は今後増加することになるだろう。

ただ正直言うと、こうしてしまいたくなる気持ちもわかる。なんせパスワードというのはたいへん面倒な代物で、アルファベットの大文字小文字混在で記号と数字も混ぜて8文字以上、なんてのが基準になってたりする。そんなもん覚えていられる人はそうそういない。

プログラマみたいな連中は1日何度もパスワードを入力する場面に遭遇するし、そのたびに入力してると指が覚えるので割と数種類のパスワードを頭に入れておくのも難しいことではない。だが普通の人はコンピュータを使う頻度もそう高くないし、「指が覚える」なんてことはまずない。となればなんとなく覚えやすい数字の羅列など、脆弱なパスワードが設定されがちなのである。

実際使う頻度の低いサービスは、パスワードどころかIDも覚えてないことが多い。俺も使うたびにパスワードを再発行してるようなサービスも割とある。

このような状況に対し、対策はいくつか思いつく。パスワードをメモした紙を財布に入れておいて誰にも見せないくらいの対策でも割と十分だったりする。ブラウザに覚えておいてもらうのでもいい。

だが根本的な対策としては、そもそもパスワード認証をやめてしまったほうがいい。

例えばキャッシュカードの事例を思い出そう。あれはカードを本人だけが持っていることが前提であり、その上でたった4桁の数字をパスワードとして認証に使い、それで何十年もそれなりのセキュリティを確保してきた。

現在「二段階認証」として認証後に携帯電話のSMSで4〜6桁程度の数字を受信し、それをウェブ画面に入力する、という手段がよく取られている。このような方式は携帯電話をキャッシュカードのように、「本人だけが持っていることが前提」にしたセキュリティだ。

こうした方式が取れる現在なら、思い切ってアカウント作成時に携帯電話番号を入力してもらえばどうだろう。ユーザーが入力するのは自分の携帯電話番号とSMSで送られるいわゆるワンタイムパスワード、それから4桁の暗証番号だけでいい。

もちろん銀行のように1日の試行回数を制限するなどする必要もあるだろうが、携帯電話の普及した今ならこのような方式も取れるのではないか。

もちろんSMSを送る料金がかかるので、コストはそれなりにあがるだろう。だが利便性と安全性を両立させる必要があるところでは、これくらいのことはしてもいいのではないだろうか。

しかしブルートフォース攻撃と言われるようなとにかく試行回数を増やす攻撃を食らうと、大量のSMSを発行することになりコストが膨大になるように思える。現在の二段階認証のように、暗証番号が正しかった時だけSMSを送るといった方法が必要になるかもしれない。

では携帯電話を持っているという前提から1歩押し進めて、スマートフォンを持っているという前提にまでいけたらどうか。

この方法ならたとえばQRコード認証というのが考えられる。LINEのパソコン版などで採用されてる方法だが、専用のアプリケーションで画面のQRコードを読み取ってもらい、そのデータをサーバに送信する。発行したデータと同一であれば認証が通る。

だがこれはパソコンと携帯電話を持っていることが前提だ。携帯電話の画面に表示されてるQRコードをその携帯電話自体で読み取ることはできない。携帯電話だけしかもってないときは認証できなくなる。

となると、逆にワンタイムパスワードを画面に写し、それを専用のアプリケーションから入力してもらうという方法ならどうだろうか。

全体のフローとしては以下のようにする。

  1. ユーザーに専用アプリケーションを自分のスマートフォンにインストールしてもらう
  2. 新規起動するとサーバ側からユーザー固有のIDが発行される(ユーザーは意識しなくていいが、デバイス登録という形でユーザーに名前を付けさせる必要はあるかも)
  3. アプリケーションは発行されたIDと携帯電話番号をサーバに送信する
  4. 電話番号が本人のものであるかを確認するため、SMSで確認用URLを送信する
  5. おそらくうっかり踏んだりするので、URLにアクセスした先で「登録した覚えがありません」ボタンか「登録したいです」ボタンを押してもらう。ここは誤認のないよう注意して作る必要がある
  6. 「登録したいですボタン」が押されたら、サーバーは受け取った携帯電話番号とユーザー固有IDを紐付けておく

ここまでがユーザー登録、およびデバイス登録操作だ。

ログインのフローは以下のようになる。

  1. ブラウザからログイン画面にアクセスすると、携帯電話番号の入力が促される
  2. 携帯電話番号が登録済みのものであることを確認し、ワンタイムパスワード(4〜6桁の数字)を画面に表示し、専用アプリケーションから入力することを促す
  3. ユーザーは専用アプリケーションからワンタイムパスワードを入力し、アプリケーションは固有IDと携帯電話番号とともにワンタイムパスワードを送信する

この方法なら固有IDが盗まれでもしない限りそう簡単にクラックされないのではないだろうか。操作も簡単で、らくらくスマホのような機種の対象者でも容易にできるだろう。アプリケーションからはワンタイムパスワードの取得から送信しなおしまで全部できるのでユーザーは何もする必要がない。

さらにセキュアにするために、アプリケーションが保存する固有IDを取り出すのに4桁の暗証番号が必要であるとか、機種が対応してれば指紋照合が必要であるとかというのを加えるのもいい。

お気づきの方もいるだろうがユーザー固有IDは実質的に保存済みパスワードとして機能するので、サーバへの保存はsaltとともにハッシュ関数を通したものを保存しておく必要はあるだろう。長さもどうせ機械が覚えてるのだからとんでもなく長くしていい。機種変更時や携帯電話のクラッシュ時には新規デバイスとして登録しなおしてもらう。

肝心のアプリケーションのインストールにパスワードが必要になるのだが、これは補助をする人がいたり、iPhone の Touch ID のような仕組みでなんとかしてもらうしかないかな。

電話番号が変わった場合が問題なのではあるが、そこまでいくとだいぶ例外的なので書面でのやりとりで十分かもしれない。

とにかくパスワード認証は不便で使いにくく普通の人に使わせると安易なパスワードを設定しがちでどのみちセキュリティを確保するのは難しい方式だ。認証という部分にもっと深く斬りこむ必要はあるだろう。

今後ウェブサービスの重要性は高まるばかりになるだろう。電子マネーや資産管理システムなどの普及により犯罪者が狙うサービスはどんどん増えていく。そしてパスワード認証が(主にユーザーに扱い切れないという意味で)どうしても脆弱になりがちである以上、ユーザーがパスワードを覚えておいたりメモしておいたりする必要のない認証方式の模索が求められていると思うのである*1

*1:作る側としては果てしなくめんどくさいのでよい感じの認証フローが確立してライブラリ化されてそれ使うだけでおっけーみたいな状況になってほしい

Sugano `Koshian' Yoshihisa(E) <koshian@foxking.org>