新春特別企画

パスワードレス認証WebAuthnの勘所と対応状況

この記事を読むのに必要な時間:およそ 5 分

はじめに

先日発表された,ヤフー株式会社の指紋認証でのログインや,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います。

※1
FIDO Alliance Webサイト「FIDOの仕組み」より。

これによってシンプルで堅牢な,そして相互運用性が高い認証エコシステムというFIDOのコンセプトが支えられています。

公開鍵暗号については本稿では解説しません※2)⁠WebAuthnを利用するにあたっては「秘密鍵で署名をして,公開鍵で検証できる」という程度の理解で問題ないでしょう。

※2
私は結城先生の秘密の国のアリスで勉強しました。

図3 公開鍵暗号を利用した認証

画像

ただ,この署名と検証には秘密鍵を所持するという「本人確認」と,署名対象データが改ざんされていないという「否認防止」の2つの意味があることに注意してください。

実際にWebAuthnにおいて署名を行うデータは,authenticatorDataclientDataHash(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です。

※3
ここでは簡単のため,RPとFIDO認証サーバーは分かれておらず,RP=FIDOサーバーとしています。当然分離した構成も可能です。
※4
認証をAuthenticatorにRelyingするため,Relying Partyと呼ばれます。

一方Authenticatorは,認証の要求に対し適切な秘密鍵で署名を作成したり,登録の際には新しいキーペアを作成したりと,Credentialの管理を行います。同時に,ユーザーが本当に認証を行おうとしているのか,ユーザーの存在(Presence)を確認したり,本人であることを検証(Verification)したりする役割を持っています。

AuthenticatorがCredentialの管理を行うことにより,パスワードの流出といったCredentialの流出はAuthenticatorのセキュリティレベルに依存することになり,高いセキュリティレベルを担保できます。一方,デバイスに認証情報が紐づくことによる運用の変化は,十分に検討しなければいけません。

著者プロフィール

@watahani

もと本屋のソフトウェアエンジニア3年目。昨年からFIDOやWebAuthnといった認証技術について調査やコミュニティ活動を始める。YubiKey検定3級(自称)。

Twitter:@watahani
ブログ:https://blog.haniyama.com