問題
フィッシングは、ウェブにおける最大のセキュリティ上の問題です。昨年のハッキングに関連するアカウント侵害の 81% が、脆弱なパスワードや盗まれたパスワードが利用されています。この問題に対する業界の集合的な対応は、多要素認証です。しかし、実装が断片化しており、依然としてフィッシングに十分に対処できていません。Google は 2013 年から FIDO Alliance と協力し、さらに最近では W3C と共同で、あらゆるウェブ アプリケーションで使用できる標準化されたフィッシング耐性のあるプロトコルを実装しています。
WebAuthn とは
Web Authentication API は、ウェブアプリケーションにユーザー エージェントを介する認証システムへのアクセスを提供します。これは通常、USB/BLE/NFC またはプラットフォームに直接組み込まれたモジュールを介してアクセスされるハードウェア トークンであり、アプリケーション スコープ(eTLD+k)公開鍵認証情報の生成と検証を目的としています。これにより、次のようなさまざまなユースケースが可能になります。
- 少ない負担でフィッシング耐性のある 2 要素認証(パスワードと組み合わせて使用することが必須)
- パスワードなしの生体認証ベースの再認証。
- 少ない負担でフィッシング耐性に優れた 2 要素認証。パスワード不要(パスワードなしのアカウント用)。
この API は主要なブラウザのほとんどで実装が予定されており、オンラインで本人確認を行う際の UI を簡素化し、フィッシングを大幅に削減することを目的としています。
WebAuthn は Credential Management API を拡張し、PublicKeyCredential
という新しい認証情報タイプを追加します。WebAuthn はブラウザと認証システム間の通信を抽象化し、ユーザーが次のことをできるようにします。
- ウェブサイトの公開鍵認証情報を作成して登録します。
- 対応する秘密鍵を所有していることを証明して、ウェブサイトの認証を行います。
認証システムは、秘密鍵と公開鍵のペアを生成して同意を取得できるデバイスです。署名に対する同意は、FIDO2 の要件(FIDO Alliance による認証者向けの認定プログラムがあります)に準拠していれば、シンプルなタップ操作、指紋の読み取り成功、またはその他の方法で取得できます。認証システムは、プラットフォーム(スマートフォンの指紋認証スキャナなど)に搭載することも、USB、Bluetooth Low Energy(BLE)、近距離無線通信(NFC)などを介して接続することもできます。
仕組み
鍵ペアの作成とユーザーの登録
ユーザーが認証情報をウェブサイト(WebAuthn では「リライング パーティ」と呼びます)に登録する場合は、次のようにします。
- 証明書利用者がチャレンジを生成します。
- 証明書利用者は、認証情報マネージャー API を介してブラウザに、証明書利用者の新しい認証情報を生成するよう要求します。これには、デバイスが独自のユーザー認証(生体認証など)を提供するかどうかなど、デバイスの機能を指定します。
- 認証システムは、ユーザーの同意を取得すると鍵ペアを生成し、公開鍵とオプションの署名済み証明書をウェブサイトに返します。
- ウェブアプリが公開鍵をサーバーに転送します。
- サーバーは、今後の認証のために認証情報を記憶するために、公開鍵とユーザー ID を保存します。
let credential = await navigator.credentials.create({ publicKey: {
challenge: new Uint8Array([117, 61, 252, 231, 191, 241, ...]),
rp: { id: "acme.com", name: "ACME Corporation" },
user: {
id: new Uint8Array([79, 252, 83, 72, 214, 7, 89, 26]),
name: "jamiedoe",
displayName: "Jamie Doe"
},
pubKeyCredParams: [ {type: "public-key", alg: -7} ]
}});
ユーザーの認証
ウェブサイトで正しいユーザーとやり取りしている証拠を取得する必要がある場合:
- リライング パーティはチャレンジを生成し、ユーザーに登録されている認証情報のリストをブラウザに渡します。また、認証情報の場所を示すこともできます。たとえば、ローカルの組み込み認証システム、または USB や BLE を介した外部認証システムです。
- ブラウザは認証システムにチャレンジに署名するよう求めます。
- 指定された認証情報のいずれかが認証システムに含まれている場合、認証システムはユーザーの同意を受け取った後に署名付きアサーションをウェブアプリに返します。
- ウェブアプリは、署名されたアサーションを証明書利用者が検証するためにサーバーに転送します。
- サーバーで検証されると、認証フローは成功したとみなされます。
let credential = await navigator.credentials.get({ publicKey: {
challenge: new Uint8Array([139, 66, 181, 87, 7, 203, ...]),
rpId: "acme.com",
allowCredentials: [{
type: "public-key",
id: new Uint8Array([64, 66, 25, 78, 168, 226, 174, ...])
}],
userVerification: "required",
}});
https://webauthndemo.appspot.com/ で WebAuthn を試す。
今後の予定
Chrome 67 ベータ版では navigator.credentials.get({publicKey: ...})
と navigator.credentials.create({publicKey:... })
がサポートされており、パソコンでの USB トランスポート経由で U2F/CTAP 1 認証システムを使用できます。
今後のリリースでは、BLE、NFC、新しい CTAP 2 ワイヤ プロトコルなど、より多くのトランスポートのサポートが追加される予定です。また、CTAP 2 と WebAuthn によって実現される、PIN で保護された認証システム、ユーザー名やパスワードの入力に代わるアカウントのローカル選択、指紋登録などのより高度なフローの開発にも取り組んでいます。
なお、Microsoft Edge は API もサポートしており、Firefox 60 では WebAuthn がサポートされています。
関連情報
現在、より詳細なドキュメントの作成に取り組んでいます。
- WebAuthnDemo による証明書利用者の実装例
- 記事 Analysis of WebAuthn(Adam Langley 作成)
Google I/O 2018 のセッション「ウェブでのサインアップとログインの新機能」では、WebAuthn について説明しました。