WebAuthnでパスワードレスなサイトを作る。安全なオンライン認証を導入するFIDOの基本
FIDO(Fast IDentity Online)とは、公開鍵認証方式を応用し、オンライン経由で認証を行う仕組みです。パスワード認証の安全性は限界が指摘されるなか、Webサイトにおいても生体認証などパスワードレスな仕組みを導入する企業が増えており、このFIDOやWebAuthnに注目が集まっています。Capy株式会社で情報セキュリティに関する研究開発や分析などに携わる、松本悦宜さんの解説です。
こんにちは、松本悦宜(@ym405nm)です。
FIDO(ふぁいど)に関しては、昨年(2018年)から多くのメディアや技術ブログで取り上げられ、導入するWebサイトも増えています。
FIDO2プロジェクトにおいて話題になったWebAuthn(Web Authentication API)についても、主なWebブラウザやWindows Helloでサポートが発表され、幅広い利用が期待されるようになりました。
この記事では、FIDOが開発される経緯や特徴といった基本的な事柄を解説します。ご自身のシステムで導入される際に、検討の一部として活用していただければ幸いです。
パスワードが限界にきている
FIDOや、FIDOを活用した生体認証がなぜ注目を集めているのか? について改めて解説しておきます。背景として、皆さんも体感されているように、パスワードの管理というものが限界にきていることがあります。
利用者にアカウントを発行しているサイトの多くが、各ユーザの認証をIDとパスワードの組み合わせで行っています。このとき、ログイン画面に脆弱性があったり、総当たり攻撃を受けたりすることで、場合によっては第三者により不正ログインされ、アカウント情報が漏えいするなどの被害を受けることがあります。
パスワードリスト攻撃の流行
さらに2013年ごろから、パスワードリスト攻撃という攻撃手法が流行しました。
これは、同じID/パスワードの組み合わせを使い回しているユーザを狙って、別のサービスから漏えいしたIDパスワードの組み合わせを、攻撃者がそのまま他のサイトのログイン画面で試行するものです。ID/パスワードを使い回しているユーザは非常に多く、多くのサイトが継続的に被害を受けています。
パスワードの使い回しが原因なのであれば、サービス提供者としてはユーザに使い回しを止めてもらうよう連絡してお願いする対策が考えられますが、全てのユーザに対してこれを強制することは現実的ではありません。
フィッシングサイトによる被害の増加
既存サービスのログイン画面とそっくり同じページを作成して、なりすましメールやSMS(携帯電話のショートメセージ)などで誘導し、それと気づかずID/パスワードを入力してしまったユーザのアカウント情報を盗むフィッシング詐欺の被害が、継続的に発生しています。
フィッシングは、典型的には不正送金を目的としてオンラインバンキングのアカウントが被害にあってきましたが、それだけではなくオンラインゲームで使用するアカウントや、クレジットカード、SNS、宅配業者、ECサイトなど、さまざまな事例が報告されています。
ページをしっかり確認すれば、パスワードを送信する画面であるのに通信がHTTPSではなくHTTPだったり、そもそもドメインがそのサービスで利用されているものではなかったりして、フィッシングサイトだということは見分けられるのですが、フィッシングサイトのリンクを偽の警告メッセージとともに送って不安を煽るなど、攻撃が巧妙化しており、ふとした瞬間に騙されてしまうことがあります。
フィッシングサイトでID/パスワードが漏えいすることにより、不正ログインされ、場合によっては金銭的な被害を受けることもあります。
パスワードレスな認証へ
このようなパスワードに関するリスクを避けるために、パスワードの代わりにFIDOを使用して認証する方法や、FIDOを使用した二要素認証を実装することが注目されるようになりました。
FIDOによるオンライン認証の仕組み
FIDOは、Fast IDentity Onlineの略で、直訳すると「素早いオンライン認証」という意味になります。公開鍵認証方式を応用し、オンライン経由で認証を行う仕組みです。
一般には「FIDOイコール生体認証」というイメージを持たれていますが、この名称から分かるようにFIDOはオンライン認証の仕様であり、必ずしも生体認証とセットになっているわけではなりません。
ここで例として、あるシステムの認証でFIDOに準拠した生体認証をパスワードの代わりに導入する場合に、どのような手順で登録・認証されるのかを簡単に解説します。この方法は、後述するUAFという仕様をもとにしています。
登場する人物・機器としては、まずユーザと、そのユーザのスマートフォンがあります。スマートフォンの生体認証を利用しますが、FIDOではこれを認証器と呼んでいます。
次に、あなたが導入しようとするシステムです。これをFIDOでは、RP(Relying Party)と呼んでいます。導入前までは、IDとパスワードで管理されていました。
そして、FIDOの認証自体を行う認証サーバがあります。RPによっては、認証サーバとRPのサービスは同一サーバで処理されることもあります。
それでは、FIDOに登録する際と、認証する際の手順を解説します。FIDOの認証では、公開鍵暗号方式を使用しています。
登録の手順
登録の手順を下図に示します。
手順のそれぞれで、次のようなことが実行されています。
- ユーザがRPにアクセスし、登録のリクエストを送る
このときの認証には従来のID/パスワードが使用される - RPが、認証サーバにリクエストを送る
- 認証サーバが、登録時に使用するチャレンジを生成する
- あらかじめ定めている認証ポリシーとチャレンジを送る
- ポリシーをもとに、ユーザに認証を求める
生体認証の場合は、ここで認証器が使用される - 認証で使用する公開鍵・秘密鍵のペアと、鍵IDを生成する
- 生成した認証用の公開鍵と鍵IDなどを、あらかじめアプリが用意しているアテステーション秘密鍵で署名し、署名データを認証サーバに送信する
- 認証サーバがあらかじめ用意しているアテステーション公開鍵で署名を検証し、送信された公開鍵と鍵IDを保存する
- RPが結果を問い合わせ、登録を確認する
認証の手順
認証の手順を下図に示します。
手順のそれぞれで、次のようなことが実行されています。
- ユーザが、ログインのリクエストを送る
- RPが、認証サーバにリクエストを送る
- 認証サーバが認証で使用するチャレンジを生成する
- あらかじめ決めている認証ポリシーと、チャレンジを送る
- ポリシーをもとに、ユーザに認証を求める
生体認証の場合は、ここで認証器による生体認証を行う - チャレンジを認証用の秘密鍵で署名し、認証サーバに送付する
- 認証サーバが認証用の公開鍵で署名を検証する。
- RPが結果を問い合わせ認証を確認します。
FIDOによる生体認証のメリット
上記の手順により、FIDOには次のような利点があります。
- 生体認証を簡単に利用できる
- 生体情報がネットワーク上を流れない
生体認証を導入するにあたって、ユーザの手元のスマートフォンがFIDOに対応さえしていれば特別な機器は不要です。ハードウェアトークンなどの機器を利用するときでも、FIDOに対応していればそのまま利用できるため、連携も可能です。
また、登録時でも認証時でも、生体認証がユーザと端末の間で完結していることに注目してください。そのため、生体情報がネットワーク上に流れることはありません。
一般的に生体認証を使用したオンライン認証で懸念されることは、生体情報の漏えいです。例えば、指紋は一生変わらないと言われており、指紋情報はパスワードよりもセンシティブであると考えられます。
FIDOでは、ネットワーク上に生体情報が流れないため、仮にシステムが被害を受けたり、ネットワークが盗聴されたりして情報が漏えいした場合でも、攻撃者が生体情報にたどり着けないようになっています。
FIDO2とWebAuthn
FIDOには、当初からU2FとUAFという2つの仕様があります。
- U2F(Universal 2nd Factor)
- 認証器を用いた二要素認証を実現する。1つ目の認証をパスワードで、2つ目の認証をハードウェアトークンなどを用いて行う
- UAF(Universal Authentication Framework)
- パスワードを使用せず、UAFに準拠したスマートフォンなどの認証器を用いた生体認証により認証を行うことができる
FIDOの活用を進めるため、FIDOアライアンスによってこれらの仕様を拡張したFIDO2プロジェクトがあります。
FIDO2は、WebAuthnとCTAPという仕様で構成されます。中でも、目玉はWebAuthnだと考えられます。
WebAuthnは、FIDOをJavaScriptで使用するためのAPIです。このJavaScript APIを使用することによって、Webブラウザ上で各Webサービスに対してFIDOによる認証を行うことができます。
Web Authentication: An API for accessing Public Key Credentials Level 1
PCのWebブラウザを使用してWebAuthnで認証する場合、PCに付属する指紋認証や顔認証などの認証器を用います。他に、FIDO2に対応しているUSBトークンで認証することもできます。
FIDO2ではこれに加えて、スマートフォンの認証器を使用できます。スマートフォンやスマートウォッチなど、外部認証器を使用してFIDO認証できる仕組みが、CTAP(Client-To-Authenticator Protocol)として現在仕様が策定されています。
Client to Authenticator Protocol (CTAP)
CTAPでは、USBを経由する着脱型や、NFCやBluetooth/BLE(Bluetooth Low Energy)を経由する無線型がサポートされています。
WebAuthnを実際に動かしてみよう
WebAuthnは、Webブラウザと認証器があれば簡単に試すことができます。ここでは、デモサイト「WebAuthn Demo」のコードを自身の環境で動かして、WebAuthnの一連の流れを確認してみましょう。
WebAuthn Demoはオンラインで公開されており、すぐに確認することができます。ソースコードは、Adam Powers氏(@apowers313)により公開されており、自身の環境で動かすことで、動作確認やデバッグなどを試しながらWebAuthnに触れることができます。
GitHub - apowers313/fido2-server-demo: A set of FIDO2 / WebAuthn demo servers
WebAuthn Demoを起動する
WebAuthn Demoは、node.jsのアプリケーションとして使用でき、以下のようにnpm start
で立ち上げることができます。
$ git clone --recursive https://github.com/apowers313/fido2-server-demo $ cd fido2-server-demo $ npm install $ npm start
WebAuthnの機能は、Webブラウザの「安全なコンテキスト」内でのみ実行されるようになっています。このためlocalhost
の環境かHTTPS通信のみに制限されます。
安全なコンテキストとは、中間者攻撃などで通信を盗聴された場合に影響の大きいAPIに関して、動作を制限するものです。 HTTPS通信の場合、自己証明書では安全なコンテキストと見なされず、動作しません。詳細は下記のリンクを参照してください。
WebAuthn Demoを動作させるには、自身の環境を適切に調整することも必要です。
例えば、https://(domain)/
でアクセスできるようにするには、scm-config.json
を以下のように変更します(変更後はroot権限が必要になる場合があります)。
"pre-config": [{ "set-port": 443, "set-https": true, "set-domain": "(domain)", "set-body-parser": "json", "set-enable-session": true }(略)
ご自身の用意した証明書を設定する場合は以下の箇所にパスを指定します。ここでは、Let's Encryptの証明書を使用した場合を記載します。
}, { "name": "cert-manager", "type": "generic", "package": "node_modules/component-certs-static", "pre-config": [{ "set-cert-file": "/etc/letsencrypt/live/(domain)/cert.pem", "set-key-file": "/etc/letsencrypt/live/(domain)/privkey.pem" }]
WebAuthn Demoを動かしてみる
先程の「WebAuthn Demo」が正常に動作するとこのような画面が表示されます。
手元にあったYubico社のFIDO2に対応したセキュリティキーを使って登録とログインをしてみました。
Discover YubiKeys | Strong Two-Factor Authentication for Secure Login | Yubico
登録時は、[「(ドメイン名)」でセキュリティキーを使用]というダイアログが表示され、認証器を使用すると、Webブラウザがセキュリティキーのメーカーとモデルと読み取りの許可を求めてきます。
これを許可すると登録が行われます。
一方、認証時にも同様のダイアログが表示され、認証が行われます。
WebAuthnの動作をコードで確認
それでは、実際にどのような動きをしているのかコードを見てみましょう。
このデモでは、webauthn-simple-appというモジュールを使用しています。
GitHub - apowers313/webauthn-simple-app: A simple WebAuthn / FIDO2 JavaScript application
このモジュールの呼び出しは、webauthn-yubiclone/js/ux-events.js
に記載されています。
まず、登録時には、webauthn-simple-appで定義されているWebAuthnApp
クラスを、以下のように利用します。
webAuthnConfig.username = getUsernameFromEvent(event); new WebAuthnApp(webAuthnConfig) .register() .then(function(resp) { // console.log("Registration complete:", resp); });
このWebAuthnApp
は、実際にはnavigator.credentials.create()
を呼び出しています。これは、非同期に新しいクレデンシャルオブジェクトを生成するもので、引数のオプションに公開鍵を使用することで、新しいアカウントへの登録や既存アカウントへの新しい鍵ペアの関連付けを行うための認証情報を作成しています。
認証時には、以下のように書きます。
var waApp = new WebAuthnApp() waApp.username = "me"; waApp.login() .then(() => { alert("You are now logged in!"); }) .catch((err) => { alert("Log in error: " + err.message); });
ここでは、navigator.credentials.get()
を呼び出します。これは同様に公開鍵を指定することで、WebAuthnの認証処理を行うことができます。
WebAuthnのドキュメントやデモサイト
こういったAPIの詳しい仕様に関しては、WebAuthnを策定しているW3Cのドキュメントや、Mozillaの提供しているドキュメント「MDN」に解説があるのでご確認ください。
Web Authentication API - Web API | MDN
Duo Security社のドキュメントも視覚的に分かりやすく、お勧めです。
また、上記で説明したWebAuthn Demoの他にも、現段階でお勧めのデモサイトがいくつかあります。
Auth0社が公開しているデモサイトでは、WebAuthnの処理がリアルタイムに図で分かりやすく表示されます。
Web Authentication (WebAuthn) Credential and Login Demo
Microsoft社が公開しているデモサイトでは、クレデンシャルのオプションをいくつかプルダウンメニューで選ぶことができ、さまざまなパターンで動作確認ができます。
FIDOの現状と実装時につまずきやすいポイント
FIDOを実装するにあたって、つまずきそうなポイントをいくつか紹介します。
まず、端末依存に気をつけたいということです。iOSのTouch ID・Face IDは、FIDOではなく独自の実装になります。このため、Touch ID・Face IDの対応や、別途iOSでのFIDO対応が必要になります。
WebAuthnについては、後述するようにWebブラウザのサポート状況を引き続き確認していく必要があります。
また、実際のシステムに導入する際には、いろいろな場面を検討しなければいけません。例えば端末を紛失したときの処理です。端末を紛失してもアカウントが被害を受ける可能性は低いですが、そのユーザは再度ログインすることができなくなってしまいます。ここでのアカウント復旧方法については事前に定めておくことをお勧めします。
WebAuthnをサポートするWebブラウザ
WebブラウザのWebAuthnサポート状況ですが、現在のところGoogle ChromeやFirefoxのほか、Android用の各種のブラウザなど、さまざまなWebブラウザがサポートを表明しています。
Web Authentication API - Can I use
また、Microsoft Edgeもサポートしており、Windows 10上で動作する生体認証機能であるWindows Helloにも対応されることで話題となりました。
生体顔認証 – Windows Hello - Microsoft
一方、Safariは対応していないため、他にWebブラウザの選択肢がないiOS端末では、WebAuthnを使用することができません。そんな中、2018年12月にSafariの開発版であるSafari Technology Preview ReleaseでWebAuthnがサポートされ、今後の動向が注目されています。
Release Notes for Safari Technology Preview 71 | WebKit
二要素認証などの実装事例
最後に、いま現在、FIDOがどのように活用されているかを紹介します。
Googleのアカウントでは「2段階認証プロセス」として他要素認証が可能になります。Googleでは、Gmailのスマートフォンアプリケーションを使用した二要素認証、登録した電話番号へのSMSによる二要素認証の手法の他に、セキュリティキーによる二要素認証の方法を選ぶことができます。セキュリティキーはUSBで挿入したFIDO U2Fのデバイスが使用できるとのことです。
2段階認証プロセスにセキュリティキーを使用する - Googleアカウントヘルプ
Dropboxも同様に、FIDO端末を用いた認証をサポートしています。DropboxではFIDO U2Fの他に、WebAuthnもサポートしているとのことです。
国内企業でもパスワードレスの動きが広まっています。
Yahoo! JAPANでは、パスワードリスト攻撃の対策として、パスワードによる認証を無効にし、SMSなどでのログインを開始しました。2018年10月には、FIDO2を使用し、AndroidスマートフォンのWebブラウザ上で生体認証を使用したログインに対応したと発表しました。
ヤフー、Androidスマートフォンのウェブブラウザー上でのログインが指紋認証などの生体認証に対応
LINEでは、以前からFIDOの導入を進めており、FIDOを活用したLINEのサービスへのログインを広めるとしています。また今後は、LINEログインを使用するサードパーティアプリについても生体認証を広げるとしています。
【コーポレート】LINE、サービス事業会社として世界初の 「FIDO ユニバーサルサーバー」の認証を取得
弊社Capyでも、FIDO UAFに準拠した生体認証のモジュールを開発しています。クライアントサイドにJavaScriptを設置し、サーバサイドにCapyが提供するAPIにアクセスするだけで生体認証を行うことができます。生体認証についてはiOSとAndroidで動くアプリケーションを提供しており、そのアプリケーション経由で各サービスに生体認証を実装することができます。少しややこしいFIDOの流れをより簡単に実装できるようにしていますので、ぜひお試しください。
おわりに
今回は、FIDOの基本について解説しました。FIDOは安全なオンライン認証を簡単にシステムへ導入することができる仕組みであると考えています。自身が管理しているシステムに生体認証を導入してみたいという方の参考になれば幸いです。
また、FIDOは生体認証とセットになって話題になることが多いですが、オンライン認証の仕組みとして多様性をもたせた有用な仕組みであると考えています。これで興味を持たれた方は、FIDOの詳細なデータの流れや、WebAuthnの実装について調べてみてください。