はじめに
先日発表された、ヤフー株式会社の指紋認証でのログイン や、Microsoft Accountのセキュリティキーでのログインが可能に といったニュースにWeb Authentication API(以下WebAuthn)界隈は盛り上がりを見せています。
パスワードを使わない世界を目指したFIDO Allianceと、W3Cの取り組みは大きく前進したといえるでしょう。2018年に、FIDO関連技術がここまで盛り上がった理由は、間違いなくブラウザーの対応が進んだことにあると思います。
私はYubiKeyの販売・サポート業務をきっかけにFIDOやWebAuthnといった技術領域に興味をもち、仕事・プライベートともに調査を行ってきました。もともと認証についての知識がゼロだった私には、大きな壁がいくつも立ちはだかりました。
本稿では、これからWebAuthnを学習しようとしている方に、認証初心者がつまづきそうな点や、興味深いと感じられる点として次の2つを中心に解説します。
公開鍵暗号方式を利用した認証のしくみ
デバイス(Authenticator)に紐づく秘密鍵
この2つはFIDOのコア技術と言えますが、概念が分かっていないと取っつきづらく、しかし非常に興味深い仕組みとなっています。
WebAuthnの概要
WebAuthnはFIDO2プロジェクトにおいて、WebアプリケーションとAuthenticatorを繋ぐJavaScript APIです。このAPIを利用することで、スマートフォンやPCの生体認証、あるいはセキュリティキーを利用してWebアプリケーションにログインできるようになります。
図1 WebAuthnの利用例
WebAuthnの概要は日本語ドキュメントとしては、MDNのWeb Authentication APIのページ が簡潔にまとまっており、参考になります。次の図は、WebAuthnによる登録の仕組みと各動作におけるデータの流れです。
図2 WebAuthn による登録手順と各アクションに関連する重要なデータの流れを示している
この図を見ればわかるとおり、②、③、④はブラウザーまたはOSが実装するAPIであり、アプリケーション開発者は①、⑤、⑥を実装すればよいことになります。しかしMDNでも言及されているように、ブラウザーと認証器の中で行われる処理やその結果のデータの意味を理解するためには②、③、④を理解することが不可欠です。
公開鍵暗号方式を利用した認証のしくみ
WebAuthnやFIDO認証では、パスワードを利用しないかわりに「標準的な公開鍵暗号方式を用いて堅牢な認証を実現して」( ※1 )います。
これによってシンプルで堅牢な、そして相互運用性が高い認証エコシステムというFIDOのコンセプトが支えられています。
公開鍵暗号については本稿では解説しません[2] 。WebAuthnを利用するにあたっては「秘密鍵で署名をして、公開鍵で検証できる」という程度の理解で問題ないでしょう。
図3 公開鍵暗号を利用した認証
ただ、この署名と検証には秘密鍵を所持するという「本人確認」と、署名対象データが改ざんされていないという「否認防止」の2つの意味があることに注意してください。
実際にWebAuthnにおいて署名を行うデータは、authenticatorData
とclientDataHash
(ClientDataJSONのSHA256ハッシュ計算したもの)を結合したデータです。
これらのデータの中には様々な情報が含まれています。そのうち重要なものはchallenge、そしてrpIdです。
challengeはサーバーで生成されるランダムな値です。ユーザーはchallengeに対し、秘密鍵で署名し、その署名をサーバーで検証することで認証とします。このような認証は通常、チャレンジレスポンス認証と呼ばれ、毎回異なるランダムなchallengeを生成することでリプライ攻撃を防ぎます。
rpIdはRPのIdつまり認証を行うサービスを識別するIDです(WebAuthnの文脈でRP(Relying Party)とは実際のWebサービス提供者やIdPを指します) 。このrpIdはorigin、サーバーのURLに深くかかわる値となっています。WebAuthnでは、このrpIdを含む値に署名することで、これらのデータが経路上で改ざんされていないという証明を行うことができます。
さらに、WebAuthnでは各経路上でrpIdの正当性をチェックします。つまり、rpIdとアクセスしているoriginが正当な関係にあるかを、ブラウザーやRPがチェックをします。この正当性の確認と署名の検証をすることで、不正なログインや認証情報の作成を防いでいるのです。
SMS認証やスマートフォンのワンタイムパスワードを利用した2段階認証では、巧妙なフィッシングサイトを作成し、認証をバイパスするといった攻撃が可能です。しかしWebAuthnでは、そもそもoriginが異なるWebサイトでは認証を行えないようにプロトコルレベルでフィッシングを防ぐため、そのような攻撃は成功しません。
これは逆に言うと、originが異なるサービス間では同じ認証情報を利用できないということです。例えばパスワード認証では、shop.example.comとshop.example.jpで同じパスワードDBを見る、あるいはパスワード同期をすることが可能です。しかしWebAuthnではCredential(パスワードに相当)はrpIdに紐づくため、同じCredentialを別のoriginで利用できません。異なるoriginで認証情報を連携するにはOIDCなどの認証連携を行うシステムが必要となってきます。
Authenticator(認証器)
FIDOやWebAuthnでは、当たり前の単語として出てくるAuthenticatorですが、こちらも開発者にとってわかりにくい概念となっています。ここではClientをWebAuthnの中心人物であるブラウザーに絞って、現在存在するAuthenticatorとブラウザーの関係を解説します。
図4 Authenticator、Client、RPの関係
WebAuthnにおいてClientであるブラウザーは、RP[3] からの認証要求を、Authenticatorに適切に伝える役割を持ちます[4] 。またAuthenticatorの列挙や、どのoriginへの認証なのかをユーザーに表示する役割も持っています。WebAuthnのAPIが実装されるのもまたClientです。
一方Authenticatorは、認証の要求に対し適切な秘密鍵で署名を作成したり、登録の際には新しいキーペアを作成したりと、Credentialの管理を行います。同時に、ユーザーが本当に認証を行おうとしているのか、ユーザーの存在(Presence)を確認したり、本人であることを検証(Verification)したりする役割を持っています。
AuthenticatorがCredentialの管理を行うことにより、パスワードの流出といったCredentialの流出はAuthenticatorのセキュリティレベルに依存することになり、高いセキュリティレベルを担保できます。一方、デバイスに認証情報が紐づくことによる運用の変化は、十分に検討しなければいけません。
cross-platform Authenticatorと platform Authenticator
ClientとAuthenticatorが明確に分かれていることにより、セキュリティキーのような外部デバイスを利用すると、ひとつのキーを別々の環境で利用できる相互運用性が生まれます。またユーザー認証の方法は、各Authenticatorにより異なり、生体認証を用いた認証やPINによる認証など、Authenticatorを入れ替えることによって、ユースケースにあった認証方法をサーバー側はほとんど意識することなく選択可能です。このような外部Authenticatorはcross-platform Authenticatorと呼ばれ、それらとブラウザーとのやりとりはCTAP(Client To Authenticator Protocol)として標準化されています。
しかし、実際のところセキュリティキーのような外部デバイスだけがAuthenticatorではありません。
図5 2種類のAuthenticator platform & cross-platform
WebAuthnではセキュリティキーのような外部認証デバイス以外に、platform Authenticatorと呼ばれる、「 Platform」に紐づいたAuthenticatorが定義されています(上図②) 。「 Platform」とは、すなわち「Windows」や「Android」などであり、WebAuthn互換のAPIが各種プラットフォームに用意されています。ブラウザーがそれらのAPIを呼び出すことで認証を行います。ただしこれらのAPIは、CTAPのように標準化されているわけではないため、各ブラウザーやOSベンダーが独自に実装を行うことになります[5] 。
すでにいくつかのプラットフォーム上では実装が進んでおり、Android上ではモバイル版ChromeがAndroidのAPIを呼び出し、指紋やPINを利用して認証を行えます(ヤフージャパンで実装されたのは、こちらのAPIを利用しています) 。
またWindows 10上のMicrosoft EdgeはWindows 10のAPIを呼び出し、Windows HelloがAuthenticatorとして振舞います。MacOSではChromeがKeyChainのAPIを呼び出して認証を行います。いずれの場合においてもTEEやTPMといったセキュアデバイス、あるいはそれに準ずるセキュアな領域にキー情報を保存します。
図6 Platform Authenticatorの例(Android)
ところで、外部・内部Authenticatorを問わず、WebAuthnでは認証情報はデバイスに依存することになります。例えばスマートフォン上で作成した認証情報は、そのスマートフォンでしか利用できません。またユーザー認証を行うための指紋やPINなどの情報もデバイスに紐づきます。
これは従来のパスワード認証のような「デバイスを問わず利用できる認証情報」と大きく異なる点です。WebAuthnではデバイスを紛失した場合、認証情報も同時に失われます。そのため、デバイスの紛失に対するアカウントリカバリの方法も検討しなければなりません。GitHub上でも盛んに議論されており 、秘密鍵をクラウド上にバックアップする仕様や、アカウントリカバリ用バックアップキーの仕様などが提案されています。その他にもセキュリティを担保するためには、デバイス紛失時には、直ちに対応するキーペアを無効化するなど、対策が必要になります。
デバイスの紛失やアカウントリカバリの他にも、検討すべき点はあります。ユースケースとして、PC上のブラウザーやアプリケーションでのログインを、スマートフォンを利用して行いたいというケースがあるかと思います。その場合、WebAuthnのスペックのみでは、PUSH通知や認証情報の受け渡し等が足りず個別の実装が必要になります。
図7 Push通知による他デバイスの認証
例えば上図の②、④はスペック外のため独自の実装となります。
このような認証を単純に実装すると、ログイン画面を偽装し、本物のサービスとバイパスすることでフィッシングが可能になってしまいます。
図8 Push通知によるログインへのフィッシング攻撃
フィッシングの可能性を指摘しましたが、このようなユースケースは決して非推奨ということではありません。ここで注目してほしいのは、WebAuthnはあくまで認証プロトコルであり、RPとClient、そしてAuthenticatorになるデバイスという経路においてはフィッシングを防げますが、それ以外の部分には関与しないという点です。つまり、インターネットを経由した他デバイスからの認証を実装する場合や、認証後の認可フローを検討する場合は、ユースケースに応じた対策が必要になります。
さて、このような攻撃を防ぐ方法の一つとして、スマートフォンをPCとCTAPプロトコルで接続することが考えられます。スマートフォンとPCがCTAPでつながると、先ほど話したとおりWebAuthnの認証は正しいrpIdとoriginの組み合わせでのみ行われるため、上記のような攻撃を防ぐことができます。
ただし、この場合フィッシングに対しては強くなりますが、PCとスマートフォンを何かしらのインターフェイスで接続することが必要になります。
図9 CTAPによるスマートフォン認証
最も現実的なのはBLEを利用することですが、通常BLEは事前のペアリングが必要で、利便性が高いとは言えません。それに対しChromeではcaBLE と呼ばれるBLEの接続方法を検討しているようです。
各プラットフォームの対応状況
最後にWebAuthnの各プラットフォーム対応について紹介します。
昨年8月に@AdamPowerが作成したFIDOとWebAuthnの採用状況の図 を参考に、先日発表されたWebkitのWebAuthn対応[6] など、私の知る限りのアップデートを加えたのが次の図です。
図10 各ブラウザの対応状況
U2F APIは現在Chromeでしかサポートされていません。一方、他のブラウザーでも実装が進んでいるWebAuthn APIはFIDO U2F対応のセキュリティキーでも利用できます。またU2Fのユースケース(2段階認証)もサポートしており、かつ移行方法も準備されています。そのため、今後はWebAuthn
APIが主流になり、Chrome以外のブラウザーがU2F APIをサポートすることはないでしょう。
一方ブラウザー下部のCTAP1/U2F、CTAP2は、セキュリティキーの対応情報を表しています。CTAP1がU2Fプロトコルに対応したセキュリティキーへの対応状況、CTAP2はそのままCTAP2対応[7] のセキュリティキーです。そしてplatformにはplatform-authenticatorの対応状況を示しました。
また、CTAP2ではU2Fと同等の機能に加え、PINによるユーザー認証、Resident Key(rk)によるユーザー情報の保存、Resident Keyが同一のrpIdに対し、複数のCredentialを持つ場合、それをリストアップする機能が仕様化されています。
図11 Edgeでユーザーのリストアップを行った例
これらの機能はWebAuthnをサポートする、ブラウザー上[8] に実装されます。
PINの入力と、複数のCredentialをリストアップするUXは現状Edgeのみで利用可能です。そのためCTAP2の新機能を試す場合は、最新のWindows 10のEdgeを使うことになります。
この図を眺めていると、Edgeの実装の進み具合には驚かされます。しかしWebKitが実装を始めたことにより、主要ブラウザーすべてが対応する日も近いのかもしれません。
WebAuthnは基本的にはブラウザーのAPIですので、その動作はブラウザーに依存します。そのためブラウザーの実装による差異は非常に気になるところであり、2019年各ブラウザーの動きに注目していきたいところです。
WebAuthnを試す
WebAuthnのデモサイトはいくつかあります。おすすめなのがMicrosoftが提供しているデモサイト「WebAuthn Test App 」です。
このデモサイトではWebAuthnの様々なオプションを切り替えて実験ができるため、ブラウザーの対応状況を確認したり、動作の違いを確かめたりすることができます。先ほどの各ブラウザーの対応状況を見ながら、いろいろなオプションを変更して、WebAuthnの動作を確かめてみてください。
図12 WebAuthn Test Appで試せるオプション
実際にサーバーサイドの実装をしてみたいという方は、少し古いですが、FIDO Alliance Sr. Certification EngineerであるYuiryのスライドが入門としておすすめです。
最後に
WebAuthnはパスワードやOTPに代わる新しい認証として、シンプルなユーザー体験と堅牢な認証の両立を実現できる可能性を秘めた、次世代の認証APIです。アカウントリカバリの問題や、よりセキュアな実装方法の検討など、議論すべき課題がまだまだ残っていますが、技術的にビジネス的にも非常に面白い分野だと考えています。
2018年は、先に示したとおりブラウザー対応が一気に進みました。2019年は、実際のサービスがどんどんリリースされる年になるかと思います。非常に楽しみですね。
今年も引き続き、WebAuthnの最新動向を追ってID界隈で活動していきますので、どうぞよろしくお願いいたします。
参考サイト