ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
パスキーについて
セキュリティをアップグレードしましょう:アカウントセキュリティを大幅に強化しながら、ユーザにすばやく簡単なサインインエクスペリエンスをもたらすパスキーのサポートを追加する方法を紹介します。パスキーは、フィッシング攻撃を排除するために構築された、シンプルで強力なクレデンシャルです。パスキーが、どのようにセキュリティを考慮して設計されているかをはじめ、パスキーの使用方法、ログインフローにパスキーを統合する方法、この機能を取り入れる際に必要なプラットフォームやWeb APIについて解説します。
リソース
関連ビデオ
WWDC23
WWDC22
WWDC20
-
ダウンロード
♪ メローなインスト ヒップホップ ♪ ♪ こんにちは Garrettです Authentication Experienceチームの エンジニアです このビデオでは 次世代認証技術である パスキーについて お話させていただきます しかしその前に 現在の認証技術である パスワードについて お話しする必要があります パスワードでほぼすべての AppやWebサイトに サインイン していることでしょう パスワードは安全に 使うのが本当に難しいです すべてのアカウントに安全で ユニークなパスワードを 作成する必要があることは 誰もが知っていますが 実際に実行している人は それほど多くはありません AppやWebサイトを設計する際 アカウントの安全性を保つ事と 優れたユーザー体験を 設計することは 常にトレードオフの 関係にあると言えます またAppやWebサイトが すべて正しく動作していても フィッシングやパスワードの 再利用などの問題により アカウントの漏洩に つながる可能性があります macOS MontereyとiOS15では そのソリューションである パスキーの開発者向け プレビューを発表し 非常に多くの素晴らしい フィードバックを頂きました macOS Venturaと iOS16ではパスキーを 誰もが使えるように することが可能になります 今が採用のチャンスです パスキーはパスワードよりも ユーザー体験が 優れているだけでなく 脆弱なクレデンシャルや クレデンシャルの再利用 クレデンシャルのリークや フィッシングなど セキュリティ問題が 全カテゴリにおいて改善されます しかもとても 使いやすくなりました お見せしましょう まずは私たちお気に入りの デモApp「Shiny」から このAppは1日1枚 かわいい写真を見ることができ パスワードによる典型的な サインインフローを採用しています ユーザー名のフィールドを タップすると 私のアカウントの 自動入力候補が表示されます 選択しサインインします そしてパスワードを 入力できます
そしてワンタイムコードが 書かれたSMSメッセージが届くまで 少し待ちます
来ました これでサインインできました いくつかのステップが必要でしたが AutoFillとパスワードマネージャーの 助けを借りて なんとかたどり着けました
サインインできたのでこのアカウントに パスキーを追加してみます 「アカウント管理」「パスキーの追加」 ここでパスキーを作成の為の システムシートが表示され 続行 できました 数回のタップで 私のデバイスは アカウント用にユニークで 暗号的に強力なキー・ペアを 生成しそれをiCloud キーチェーンに保存します macOS Venturaと iOS16を搭載した すべてのデバイスで 同期して機能します
ではパスキーができたので その使い方を紹介しましょう サインアウトします 先ほどと同じ サインインフォームに戻ります 前回と同様にユーザー名 フィールドにフォーカスを当てます 現在私のアカウントに パスキーが保存されており QuickTypeバーに 表示されます タップするだけで サインインできます ワンステップです パスキーを保存する際 新しいパスワードを考えたり 複雑な条件を 満たそうとしたりする 必要はありませんでした 各パスキーはシステムに よって生成され 強度が保証されており 1つのアカウントに のみ使用されます それでサインインするときは 慣れ親しんだ 既存のサインインフローで 表示でき ワンタップで使えるように なっています そして正しいAppや Webサイトでしか使わせないよう システムが配慮し 強力なフィッシング対策が 組み込まれています もちろんパスキーは Web上でも有効です ここではSafariでシャイニーの Webサイトを表示しています 携帯電話と同じように ユーザー名フィールドにフォーカスすると iCloudキーチェーンのおかげで 私のパスキーが 既にそこにありすぐ 使えるようになっています Touch IDだけで サインインできるんです それだけです Appleのパスキー実装はオープン スタンダードをベースに構築されています 私たちはFIDO アライアンス内の他の プラットフォームベンダと 協力しパスキーの実装が クロスプラットフォームで 互換性を持ちできるだけ 多くのデバイスで 動作するように努めています アカウントをパスキーに アップグレードしても 友人のPCから サインインできます もちろん友人のPCはローカルに パスキーが保存されていませんが ここで自分のユーザー名を 入力することができます サインインを押すと iPhoneを使うためのオプションが 表示されたシートが現れます するとQRコードが 表示されるのでスキャンします
iPhoneが このQRコードはパスキーを使って サインインするための ものだと認識するので このオプションを選択すると iPhoneとブラウザが セキュアに接続されます これで「続ける」だけで サインインできました このクロスプラットフォームの サインイン体験は パスキーの背後にある 標準の一部であり ファーストクラスの システム機能です 一見とてもシンプルに 見えますが これは単なる QRコードではありません 裏では各デバイスがローカルな キーの照合を行い 近接性を確認します エンドツーエンドで 暗号化された通信路を確立し 簡単な方法でサインイン できるようにしながら パスキーの持つ強力な フィッシング耐性を維持します どのデバイスからでも 自分のアカウントに 安全にサインインできるのは 素晴らしいことです またパスワードの置き換えに 重要な機能として 2人以上の間でアカウントを 共有できることが挙げられます パスキーは AirDropで 共有することができます
私とパートナーが 共有しているShinyのアカウントは すでにパスキーを使用するように アップグレードしています パスキーの場合クレデンシャルは 入力できるものではありませんが それでも信頼できる人と 共有することができます iPhoneでアカウントの 詳細を開いてみます
以下はパスワードと パスキーの 両方を使用している 私のすべてのアカウントです 共有アカウントをタップして 詳細を確認することができます ここでは保存したパスキーに 関する情報を取得したり このアカウントにメモを 追加できます パスキーの共有も可能です パートナーのiPhoneがあります 先にそれを選択しておきます
今私のパートナーも パスキーを使っています
パスキーはどこでも簡単に 使えるということです パスキーの使い方は 先ほど説明したとおりです 次にパスキーとは何か そしてパスキーを使用する際の インターフェイスのガイドラインに ついて説明します 次にAutoFillを利用し AppやWebサイトの 既存のサインインフローに パスキーを 統合する方法を紹介し さらに サインインプロセスを 効率化するための 追加オプションを紹介します その後パスキーの 仕組みについて もう少し技術的に 詳しく説明し 最後にパスキーと 多要素認証について説明します まずはパスキーの デザインについてです パスキーについて 説明する前の前提として 第一にパスキーはパスワードの 代わりとなるものです より速くサインインでき より使いやすく そしてより安全です AppやWebサイトでの パスキーの参照方法について いくつかのガイドラインを ご紹介します パスキーはユーザーが目に する一般的な用語です このビデオはAppleの実装に 焦点を当てていますが 先ほど紹介したように 他の主要なプラットフォームでも すでにパスキーの独自サポートの 構築が始まっています 「パスキー」は「パスワード」と 同じように普通名詞でもあります 英語では小文字で "password "のように 複数形になることを 意味します 私のアカウントには パスキーがあり 設定からパスキーのある アカウントを表示できます Appleのプラットフォームでは SF Symbolsの person.key.badgeと .fillのバリアントも使用でき システムと一致したアイコンを 提供することが可能です AppやWebサイトで パスキーを提供する場合 新しいインターフェイスを デザインする必要はありません ユーザー名フィールドは ほとんどのAppやWebサイトの サインインの中心的な ポイントです 多くの人がその使い方を 知っており すでに多くのAppやWebサイトが アカウントごとにサインイン体験を カスタマイズするために 活用しています ユーザー名フィールドには もう一つ大きな特徴があります パスキーはサインインの 仕組みに新しい パラダイムをもたらしますが パスワードからの移行もスムーズで 簡単であることが必要です AutoFillを 使用したパスキーは ファーストクラスの 機能として 既存のサインインフローに そのまま 組み込むことができます AutoFillでパスキーを 提示するのが 主な使用方法です しかしより高度な使い方のために Appleのプラットフォームでは パスキーによる サインインのための幅広い 追加UIオプションも 用意されています ここではパスキーの 使用方法とAutoFillでの 提示方法に ついて説明します パスキーはWebAuthentication またはWebAuthn標準に 基づいて構築され 公開鍵暗号を使用します 入力可能な単語や 文字列を持つのではなく アカウントごとにユニークな 暗号キーペアを生成します パスキーサインインを行うには サーバのバックエンドに WebAuthnを採用する 必要があります 標準的なWebAuthn サーバの実装であれば パスキーで動作するはずです Appleプラットフォーム上の Appでは パスキーはAuthenticationServices フレームワークの ASAuthorization API ファミリーに含まれます これはパスワード セキュリティキー Appleでサインインなど あらゆる種類の クレデンシャルを 扱うためのAPIです またこのAPIをより柔軟にし 既存のサインインフローに シームレスに適合させるために AutoFillサポートなど 使用できるいくつかの 新メソッドを追加しています Appでパスキーを 使い始めるには まずwebcredentialsの サービスを使用して 関連するドメインを セットアップする必要があります その詳細はビデオ 「Introducing Password AutoFill for Apps」と 「ユニバーサルリンクの新機能」 でご確認いただけます Appのインターフェイスで ユーザー名フィールドが usernameのtextContentTypeを 使用していることを確認します これによりシステムはパスキーの 提案を行う場所を把握できます これが設定されるとAutoFillによる パスキーのリクエストを スタートするために必要な コードは次のようになります 分解してみると ステップはシンプルです 他のWebAuthn リクエストと同様に まずサーバからチャレンジを 取得する必要があります 次にプロバイダと リクエストを作成します ASAuthorizationPlatform PublicKeyCredentialProviderは パスキーリクエストを扱うための ASAuthorizationProviderです WebAuthn的にはアサーションは サインイン時に使うものなので ここでは既存のパスキーで サインインするための アサーションリクエストを 作成しています ASAuthorizationControllerは 実際にリクエストを 処理するためのものです パスキーリクエストのインスタンスを 生成しそのデリゲートと presentationContext Providerを設定します そして最後にperformAutoFill AssistedRequestsを 呼び出してリクエストを 開始します このリクエストがAppで 実行されている間 ユーザー名フィールドが フォーカスされるたびにシステムは QuickTypeバーに利用可能な パスキーを提供します キーボードが表示された時に パスキーの準備ができるように ユーザー名フィールドが フォーカスされる前に ビューライフタイム内の早い段階で リクエストを開始するようにしてください QuickTypeバーから 項目を選択すると Face IDが呼び出され ASAuthorizationController Delegateコールバックを 受け取ってサインインが 完了します テキストフィールドに実際に 入力されるものは何もありません 任意のクレデンシャルタイプで 認証が成功すると didCompleteWithAuthorization コールバックを 受け取ります 最初にやることは受け取った クレデンシャルの種類を 確認することです パスキーサインインの場合は ASAuthorizationPlatformPublicKey CredentialAssertionが使用されます アサーションオブジェクトには バックエンドでサインインを 検証するために必要な フィールドが含まれます 値を読み込み その値をサーバで確認し サインインを 完了させる必要があります AutoFillアシストによる パスキーリクエストは強力です この小さなコード変更で Appのサインインフローが 柔軟になりました もちろんQuickTypeバーから パスキーの提案を選択し そのパスキーで 素早くサインインすることが プライマリのケースとなります これが一番多いと 思ってください 他にも選択肢はあります 先ほど紹介したコードでも 追加の変更なしで 近くのデバイスからパスキーに よるサインインが可能です 鍵のアイコンをタップすると 利用可能な すべてのパスキーと パスワードの一覧が表示され 近くのデバイスでサインインする オプションが表示されます するとデバイスをまたいだ サインインが可能になります どちらの場合も パスキーが使われていれば 同じASAuthorization ControllerDelegateの コールバックを受け取ります これをサポートするために 必要なことは特にありません もしユーザーがまだ多くの パスキーを持っていないなら 慣れたようにログインフォームを 使用することもできます パスワードは QuickTypeバーで提案され フィールドに 入力することもできます パスワードのアイテムが 選択されると クレデンシャルは テキストフィールドに入力され 実行中のリクエストを キャンセルできます このAPIは既存のサインイン フローに持ち込むことで ユーザーが簡単に サインインできるように 設計されています すでにパスキーの使用に アップグレードした人が AutoFillの提案を 使用せずに ユーザー名を入力する ことにした場合は AutoFillのリクエストを キャンセルして ASAuthorizationControllerを使用して モーダルパスキーサインインシートを 表示する必要があります ここからは やはりシングルタップで 同じASAuthorization ControllerDelegateの コールバックを 受け取ります 以下は以前のコードです これをAutoFillリクエストから モーダルリクエストに切替えるには このperformAutoFillAssisted Requestsメソッドコールを performRequests()コールに 置き換えるだけです これにより利用可能なすべての パスキーと近くのデバイスの パスキーを使用するオプションが モーダルシートで表示されます パスキーに対応するために Appで必要なコードの変更は これだけです またWebプラットフォームは AutoFillアシストと モーダルパスキーの両方の リクエストに対応しています Web上ではセキュリティキーにも 使用される 標準的なWebAuthn APIを 介してパスキーが使用されます Appと同じように AutoFillアシストのリクエストを 採用することでTouch IDだけで 素早くサインインし 利用可能なすべてのパスキーと パスワードを取得したり 近くのデバイスから パスキーを使用したり わずかなコードで すべて行うことができます まず最初にWebページの ユーザー名フィールドに usernameとwebauthnの両方の オートコンプリート 詳細トークンを注釈して パスワードとパスキーの 両方の候補が 正しい場所に表示される ようにしてください これが完了したら JavaScriptで典型的な WebAuthnのサインインを 行います WebAuthnではAutoFill スタイルのリクエストは 条件付き仲介を 使用して呼び出されます まずは標準的なJavaScriptの 機能検出を利用して 利用可能かどうかを 確認することから 始める必要があります そうであればそのまま リクエストしてください ネイティブAPIと同様に サーバから取得したchallengeを 使用してリクエストを 行うことから始めます AutoFillアシストのリクエストにするには medationを追加します 「conditional」パラメータを オプションに追加ください 次にnavigator.credentials.getを使用し リクエストを開始します .getコールは promiseを返します 解決した場合は アサーションオブジェクトを受け取り それをサーバに 送り返して検証し サインインを 完了させることができます Appのように誰かが手動で パスキーを使ってアカウントの ユーザー名を入力した場合 APIを使って モーダルサインインシートを 提示する必要があります モーダルリクエストに 切り替えるために必要なのは conditionalパラメーターを 削除するだけです WebAuthnを使用する際の 注意点として Appleのプラットフォームがユーザー認証(UV)を どのように扱うかが挙げられます UVはWebAuthnレスポンスの ブール値フィールドで 認証機関が現在のユーザーが デバイスの所有者で あることを 確認しようとしたか どうかを示します Appleのデバイスでは 値が1の場合 生体認証 またはパスワードやパスコードが 使用されたことを示します Appleのプラットフォームでは 生体認証が利用できるようになると 必ずパスキーのためのUVを 要求するようになるので その心配はありません WebAuthnリクエストの際に ユーザー認証の要件を 指定するオプションがあります デフォルトはuserVerification: 「preferred 」 生体認証のないデバイスで 悪い経験をさせないために 常にデフォルト値を 使用します Web上でパスキーを使用する際の 注意点をいくつかご紹介します AutoFillアシストのリクエストを 行う場合は Appと同じように ページライフタイムの 早い段階で行う 必要があります モーダルなWebAuthnリクエストの場合 ボタンのクリックなど ユーザーのジェスチャイベントを トリガにする必要があります モーダルリクエストはユーザー ジェスチャイベント以外の ページ読み込み時に1回だけ 起動できますが そうすると WebKitがそのページでの後続の 呼出しを制限する場合があります AutoFillのリクエストは モーダルではないので ユーザーのジェスチャを 必要とせず タイムアウトも かなり長くなります 最後にパスキーは Safariのレガシーである プラットフォーム認証に 取って代わります 既存のクレデンシャルは 引き続き機能し 作成されたデバイスに バインドされますが 新しいプラットフォームのクレデンシャルは パスキーとして作成されます パスキーは証明書を 提供しないので 登録時にレガシー クレデンシャルと 区別することができます これがパスキーと AutoFillです 次はサインインを さらに効率化するための プラットフォーム機能に ついて説明します ASAuthorization APIは AutoFillによる サインインに加え さらに多くの便利な 機能を提供します 今回はAPIの追加機能を 3つ取り上げ どのような場合に 使えるのかを紹介します パスキー許可リストを 始めとして ユーザー名入力後に パスキーシートを モーダルに表示する場合 端末に複数の アカウントのパスキーが 保存されている 可能性があります デフォルトでは利用可能な 全パスキーがシートに表示されます またパスキー許可リストを 使用するとシートに表示される パスキーを制限し 一致するアカウントのみが 提供されるように することができます モーダルリクエストに 許可リストを追加するには まずユーザー名が必要です そのユーザー名を使って一致する クレデンシャルIDのリストを取得し それを許可リストに することができます クレデンシャルIDは パスキーの一意な識別子です WebAuthnサーバは 与えられたユーザー名の クレデンシャル IDを検索する方法を 持つ必要があります ここからは同じように リクエストを進めてください 今私の端末には3つの Shinyアカウントがあり パスキーを使っていますが シートには私が使おうとしている 1つのアカウントしか 表示されません モーダルリクエストを行う場合 ユーザーがどのアカウントで サインインしようとしているのか 例えばユーザー名を すでに入力している場合など 追加コンテキストがある時は 許可リストを使用する 必要があります 次は現在のデバイスに 保存されたパスキーがない場合 モーダルパスキーリクエストを行うと どうなるかを説明します これは許可リストを使用し 保存されたパスキーのどれもが そのリストに一致しない 場合にも適用されます デフォルトではモーダルパスキーの リクエストを行った際 一致するパスキーが ない場合は モーダルシートを表示し 近くのデバイスからパスキーで サインインするための QRコードを 即座に表示するように なっています これはサインイン時に 最も柔軟性がありパスキーが 使用を把握している 場合に最適なオプションです しかしAPIに新しい オプションがあり すぐに利用できる 信用証明書を優先し それがない場合はデリゲートコールバックに サイレントでフォールバックします これを使用して可能な場合 従来のサインインフォームを 表示する前に 既存のクレデンシャルを 迅速に提供することができます デフォルトのオプションを 使用したこのモーダルリクエストは 現在のデバイスに一致する パスキーがない場合 QRコードの表示に フォールバックします preferImmediatelyAvailableCredentials オプションを使用すると QRコードを 取得する代わりに エラー付きのデリゲート コールバックを受け取ります キャンセルされたコードで ASAuthorizationErrorを 受け取った場合ユーザーが シートを見て手動で解除したか preferImmediately AvailableCredentialsを渡して すぐに利用できる 資格情報がなかったかの どちらかであることを 意味します ここからどうするかは これを呼び出した側の 文脈によります 例えば通常のサインイン フォームを表示する前に ローカルの認証情報を テストする方法として このオプションを 使用する場合 ここでフォームを表示する きっかけとなります デバイス上に少なくとも1つの 一致するクレデンシャルがある場合 使用される オプションに関係なく 完全なモーダルシートが 表示されます またAppのどこかでAutoFill アシストのリクエストまたは デフォルトのフォールバックに よるモーダルリクエストを 使用していることを確認し 現在のデバイスに パスキーがない場合でも 近くのデバイスで サインインするオプションに 到達できるようにします ASAuthorization APIの 最後の機能として 複合クレデンシャルリクエストを 行うことを説明します この例ではAppがパスキー パスワード Appleでのサインインを 要求しています 私の端末にはたまたま3つの 異なるアカウントの 認証情報が 保存されていたので ここにすべて 表示されています しかしより可能性が高いのは 1つのアカウントしか持っていないことです その場合この同じ複合 クレデンシャルリクエストでは シート内の1つの アカウントしか提供されません 既存のASAuthorization リクエストに追加の クレデンシャルタイプを 追加するのは非常に簡単です 追加のリクエストタイプに 対応するプロバイダと リクエストを作成し それらの新しいリクエストを コントローラに渡すだけです これでモーダルシートは これらのクレデンシャルタイプの いずれかから利用可能な クレデンシャルを提供します どのクレデンシャルタイプを 使用しても 同じデリゲートコールバックを 受け取ることができます 受け取ったクレデンシャルの 種類を確認し そのクレデンシャルの 種類に応じた サインインを完了する 必要があります ASAuthorization API ファミリのより高度な 機能のいくつかを カバーしています これからパスキーの 動作と安全性について 技術的な詳細を 説明します 現在パスワードを入力して サインインする場合 一般的に実際に 行われているのは パスワード入力後にハッシュ化 ソルティングを行い 難読化した値を サーバに送信し サーバがそれを 保存しています その後同じハッシュ化 された値を生成できれば そのアカウントに 入ることができる これはサーバが パスワードの派生物を 保存する責任を 負うことを意味し 攻撃者にとって非常に 価値のあるものです もしそれが手に入れば パスワードが分かり アカウントに アクセスできる可能性があります しかしパスキーは全く 違う仕組みになっています パスキーは単一のタイプ 可能な文字列ではなく 実際には関連する キーのペアです これらのキーはアカウントごとに 安全かつ一意に デバイスによって 生成されます 1つは公開され サーバに保存され もうひとつは サインインしても 端末に残る プライベートなものです パブリックキーは 秘密ではありません ユーザー名と 同じように公開されます プライベートキーはサインイン するために必要になります プライベートキーは サーバが知ることはなく デバイスが安全に保管します サインインしようと するとサーバは みなさんのデバイスに1回限りの チャレンジを送ります WebAuthnではさまざまなチャレンジレスポンス アルゴリズムが使用できますが Appleプラットフォームのパスキーは 標準のES256 を使用します ユーザーのプライベートキーだけが アカウントの チャレンジに対する有効な ソリューションを生成することができます 端末は署名とも呼ばれる このソリューションを ローカルで生成し このソリューションのみを サーバに送り返します キーは端末にのみ保存され 第三者に知られることはありません その後サーバはパブリックキーを 使ってソリューションを検証します デバイスが提供した ソリューションが有効であれば サインイン完了です パブリックキーはソリューションが 有効かどうかチェックできますが ソリューションそのものを 生成することはできません つまりサーバはプライベートキーの 実態を知らなくても みなさんが正しいプライベート キーを持っていることを 確認することが できるのです またサーバは プライベートキーを 知らないので 攻撃者のターゲットとして 価値が低いのです この暗号とキーの保護はすべて デバイスによって完全に 透過的に実行されます ユーザーはそれを知ることも 考えることもありません ユーザーにとっては パスキーは極めてシンプルで どこでも使えるものなのです またパスキーはデバイス間で サインインする際に フィッシングに強いセキュアな 方法で使用できます その仕組みはこうです ここには2つデバイスがあります クライアントとは サインインするデバイスや Webブラウザのことで Authenticatorとは 私のパスキーを持つ デバイスのことです まずクライアントが QRコードを提示し それをAuthenticatorが読み取ります このQRコードには1回しか 使えない暗号鍵のペアを 暗号化したURLが 含まれています その後Authenticatorは ネットワークリレーサーバの ルーティング情報を含む Bluetoothアドバタイズを作成します このローカルエクスチェンジでは サーバの選択と ルーティング情報の 共有が可能ですが さらに2つの機能を 備えています サーバには見えない キーの合意を行うので ネットワーク上を 流れるものは すべてエンドツーエンドで 暗号化され サーバはそれらを 読むことができません またこの2つのデバイスが 物理的に 近接していることの 強力なクレームを提供します つまり電子メールで 送信されたQRコードや 偽のWebサイトで生成された QRコードは機能しません 遠隔地の攻撃者は Bluetoothのアドバタイズを受信して ローカルエクスチェンジを 完了することができないためです それがローカルな 部分なんですね ローカルエクスチェンジと キーの合意が行われると 2つのデバイスは iPhoneが選んだ リレーサーバに接続します そこから標準的な FIDO CTAP操作を行いますが この操作は先ほどのキーを 使って暗号化されているので リレーサーバには 何も見えません
この一連の処理はデバイスと Webブラウザに よって行われます デバイス間の通信には Webサイトは 一切関与していません クロスデバイス クロスプラットフォーム サインインは パスキーが使える場所であれば どこでも使えるシステム機能です 以上パスキーの仕組みと デバイス間でも 強固なセキュリティ保証を 実現する方法について より技術的な観点から 解説しました 次は多要素認証です 現在認証を考える際に よく使われるのが 「要素」という考え方です 各要素によって得意 不得意な攻撃が異なるため 要素を組み合わせることで より優れたカバレッジが 可能となります でもパスキーを使えばもう そんなことは考えなくていいんです 現在サインインに よく使われる方法を 紹介します 頭の中にあるパスワードは かなりの確率で 脆弱なものです パスワードマネージャーは ユニークで高エントロピーの 文字列を生成することに 長けておりデバイスの盗難に対する ローカルな保護機能を 備えている場合があるほか フィッシングに関するいくつかの ヒントを提供してくれます SMSやタイムベースの コードを追加することは 状況によっては盗難や フィッシングの対策になりますが 本当の意味での 解決にはなりません しかしパスキーの場合 すべて デバイスが生成する ユニークなキーペアです Appleのデバイスでは ローカルデバイスの保護という 強力な基盤の上に 構築されています またパスキーは フィッシングから 人間の要素を 完全に排除します またAppやWebサイトのサーバは プライベートキーを持っていないので 漏えいすることはありません パスワードベースのサインインフローに 要素を追加することは パスワードだけよりも多くの種類の 攻撃から保護することができるため 理にかなっていると 言えるでしょう しかしパスキーはそれだけで 多くのことを防ぐことができるので 追加要素を必要としません パスワードのない未来が 楽しみですね それを実現するための 方法をご紹介します まず最初にサーバに WebAuthnを 導入する必要があります パスキーは標準的な WebAuthnサーバの 実装であれば 動作するはずです サーバの準備ができたら みなさんのAppやWebサイトに 新しいAPIを 導入してください AutoFillを利用した パスキーの リクエストは 既存のサインインフローに そのまま追加することが できます そして最後にユーザーを パスワードから解放することです パスキーはAppや Webサイトに安全に サインインするための利便性と セキュリティの問題を 解決する業界標準の ソリューションです パスワードではなく パスキーに誘導することで 迅速で便利なサインインを 体験してもらうと同時に すべての人の セキュリティレベルを 向上させることができます ご視聴ありがとうございます ♪
-
-
11:30 - Associated Domains setup
{ "webcredentials": { "apps": [ "A1B2C3D4E5.com.example.Shiny" ] } }
-
11:47 - Annotating user name text field
override func viewDidLoad() { super.viewDidLoad() //Additional setup… userNameField.textContentType = .username }
-
11:59 - AutoFill-assisted passkey sign in
// AutoFill-assisted passkey request func signIn() { let challenge: Data = … // Fetched from server let provider = ASAuthorizationPlatformPublicKeyCredentialProvider( relyingPartyIdentifier: "example.com") let request = provider.createCredentialAssertionRequest( challenge: challenge) let controller = ASAuthorizationController( authorizationRequests: [request]) controller.delegate = self controller.presentationContextProvider = self // Start the request controller.performAutoFillAssistedRequests() }
-
13:29 - ASAuthorizationControllerDelegate callback
// Completing a passkey sign in func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { guard let passkeyAssertion = authorization.credential as? ASAuthorizationPlatformPublicKeyCredentialAssertion else { … } let signature = passkeyAssertion.signature let clientDataJSON = passkeyAssertion.rawClientDataJSON // Pass these values to your server, and complete the sign in … }
-
16:05 - Modal passkey sign in
// Modal passkey request func signIn() { let challenge: Data = … // Fetched from server let provider = ASAuthorizationPlatformPublicKeyCredentialProvider( relyingPartyIdentifier: "example.com") let request = provider.createCredentialAssertionRequest( challenge: challenge) let controller = ASAuthorizationController( authorizationRequests: [request]) controller.delegate = self controller.presentationContextProvider = self // Start the request controller.performRequests() }
-
16:53 - HTML user name field annotation
<input type="text" id="username-field" autocomplete="username webauthn" >
-
17:09 - AutoFill-assisted passkey sign in on the web
// AutoFill-assisted WebAuthn request (JavaScript) function signIn() { if (!PublicKeyCredential.isConditionalMediationAvailable || !PublicKeyCredential.isConditionalMediationAvailable()) { // Browser doesn't support AutoFill-assisted requests. return; } const options = { "publicKey": { challenge: … // Fetched from server }, mediation: "conditional" }; navigator.credentials.get(options) .then(assertion => { // Pass the assertion to your server. }); }
-
18:14 - Modal passkey sign in on the web
// Modal WebAuthn request (JavaScript) function signIn() { var options = { "publicKey": { challenge: … // Fetched from server } }; navigator.credentials.get(options) .then(function (assertion) { // Pass the assertion to your server. }); }
-
20:55 - Modal passkey request with allow list
// Modal request with allow list func signIn(userName: String) { let challenge: Data = … // Fetched from server let provider = ASAuthorizationPlatformPublicKeyCredentialProvider( relyingPartyIdentifier:"example.com") let request = provider.createCredentialAssertionRequest( challenge: challenge) let credentialIDs: [Data] = … // Fetched from server for provided userName request.allowedCredentials = credentialIDs.map( ASAuthorizationPlatformPublicKeyCredentialDescriptor.init(credentialID:)) let controller = ASAuthorizationController(authorizationRequests: [request]) controller.delegate = self controller.presentationContextProvider = self // Start the request controller.performRequests() }
-
22:56 - Modal passkey request with silent fallback
// Modal passkey request, silent fallback func signIn() { let challenge: Data = … // Fetched from server let provider = ASAuthorizationPlatformPublicKeyCredentialProvider( relyingPartyIdentifier:"example.com") let request = provider.createCredentialAssertionRequest( challenge: challenge) let controller = ASAuthorizationController(authorizationRequests: [request]) controller.delegate = self controller.presentationContextProvider = self // Start the request controller.performRequests(options: .preferImmediatelyAvailableCredentials) }
-
23:06 - Silent fallback delegate callback
// Handling a silent fallback func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) { guard let error = error as? ASAuthorizationError else { … } if error.code == .canceled { // Either the user canceled the sheet, or there were no credentials available. showSignInForm() } }
-
24:40 - Combined credential request
// Combined credential modal request func signIn() { let challenge: Data = … // Fetched from server let passkeyProvider = ASAuthorizationPlatformPublicKeyCredentialProvider( relyingPartyIdentifier:"example.com") let passkeyRequest = passkeyProvider.createCredentialAssertionRequest( challenge: challenge) let passwordRequest = ASAuthorizationPasswordProvider().createRequest() let signInWithAppleRequest = ASAuthorizationAppleIDProvider().createRequest() let controller = ASAuthorizationController( authorizationRequests: [passkeyRequest, passwordRequest, signInWithAppleRequest]) controller.delegate = self controller.presentationContextProvider = self // Start the request controller.performRequests() }
-
25:02 - Combined credential callback
// Completing a combined credential request func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { switch authorization.credential { case let passkeyAssertion as ASAuthorizationPlatformPublicKeyCredentialAssertion: finishSignIn(with: passkeyAssertion) case let signInWithAppleCredential as ASAuthorizationAppleIDCredential: finishSignIn(with: signInWithAppleCredential) case let passwordCredential as ASPasswordCredential: finishSignIn(with: passwordCredential) default: // Handle other credential types break } }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。