An introduction to WebAuthn for Java developers
Copyright © Yoshikazu Nojima 2018Java開発者のためのWebAuthn入門2019-05-18 JJUG CCC Spring能島 良和 (@shiroica)
View Slide
Copyright © Yoshikazu Nojima 2018自己紹介• 能島良和• 通信キャリアでホスティングサービスの開発・運用• 前職は通信キャリア系SIerで社内向けにSpringのPJ支援業務• Apache CloudStack Commiter(活動休止中。。)• WebAuthn周りは趣味• Twitter:@shiroica• GitHub:ynojima1
Copyright © Yoshikazu Nojima 2018突然ですが・・・この中にオンラインサービスのアカウントを乗っ取られた経験のある方はいますか?2
Copyright © Yoshikazu Nojima 2018恥ずかしながら私はあります・・・3
Copyright © Yoshikazu Nojima 2018パスワードの限界パスワードには以下の問題があります。• フィッシング攻撃耐性• 本物そっくりの偽物サイトを作成し、ユーザーを誤認させたうえでID/Passwordを入力させ詐取• 精巧に作成されたフィッシングサイトは45%のユーザーが騙されるという研究結果も• リスト型攻撃耐性• 脆弱な他サービスで流出したID/Passwordを用いた攻撃• 自サービスは堅牢でも、ユーザーがパスワードを使いまわした場合、巻き添え被害の可能性• モバイルデバイス対応• モバイルデバイスでは複雑なパスワードの入力が不便パスワード要求はユーザーの離脱率に顕著な悪影響パスワード認証に代わる認証手段が必要4
Copyright © Yoshikazu Nojima 2018Web Authentication仕様とは最近W3Cで勧告候補になった、パスワード認証の問題点を克服したセキュアな認証を実現するためのWeb標準。セキュリティキーによる二段階認証や生体認証を実現。■主な特徴• 指紋認証や顔認証など認証方式を差し替え可能• 生体情報をサーバーで保存せず、安全性が高い• フィッシング攻撃、 CSRF攻撃対策の組込5
Copyright © Yoshikazu Nojima 2018Web Authenticationの認証フロー(概略)• ユーザー登録ユーザー 認証デバイス ブラウザ サーバーDBRP固有公開鍵の保存承認ジェスチャ(指紋スキャン等)の実施• RP固有公開鍵• Credential Id• ドメイン(RP Id)のハッシュ• その他を送信• RP固有公開鍵• Credential Id• ドメイン(RP Id)のハッシュ• その他を送信耐タンパ領域RP固有秘密鍵を保存RP固有公開鍵・秘密鍵ペアを生成• チャレンジ• チャレンジ、ドメイン(RpId)その他のハッシュクライアントデータのハッシュ、RP Idに対する署名を生成ドメイン(RP Id)チャレンジその他の検証耐タンパ領域• ローカル認証情報(生体情報等)を検証ユーザー検証機能付き認証デバイスの場合
Copyright © Yoshikazu Nojima 2018Web Authenticationの認証フロー(概略)• ユーザー認証ユーザー 認証デバイス ブラウザ サーバー承認ジェスチャ(指紋スキャン等)の実施• Credential Id• 認証デバイスデータ• RP Idのハッシュ• フラグ• カウンタ• 資格情報データ• 署名を送信• Credential Id• チャレンジ、ドメイン(RpId)その他• 認証デバイスデータ• RP Idのハッシュ• フラグ• カウンタ• 資格情報データ• 署名を送信• RP Idのハッシュ• チャレンジ、ドメイン(RpId)その他のハッシュRP固有秘密鍵でRpIdのハッシュ、フラグ、カウンタ、クライアントデータのハッシュを署名ドメイン(RP Id)、署名チャレンジ、その他の検証• チャレンジを送信ユーザー検証機能付き認証デバイスの場合耐タンパ領域• ローカル認証情報(生体情報等)を検証RP固有秘密鍵を読込ローカル認証 公開鍵認証DBRP固有公開鍵の読込
Copyright © Yoshikazu Nojima 2018WebAuthnの技術的な特徴ローカル認証と公開鍵認証の組み合わせ• ローカル認証• ユーザーと認証デバイス間の認証認証方式は交換可能(例:指紋認証、虹彩認証、PIN)• 公開鍵認証• 認証デバイスとサーバー間の認証8ユーザー 認証デバイス サーバーローカル認証(指紋認証等)公開鍵認証
Copyright © Yoshikazu Nojima 2018生体認証をローカル認証とするメリット生体認証をリモート認証とした場合のリスク• 生体情報は変更不可能なことから究極のプライバシー情報。取扱は慎重さが求められる• サーバーに生体情報を保存する生体認証では、生体情報は経路上で様々な攻撃に晒される• WebAuthnでは生体情報が認証デバイスから外に流通せず、安全性が高い(ローカル認証)• クライアント(ブラウザ)とサーバーは公開鍵と、公開鍵で検証できる署名を受け取るのみ• 生体情報と秘密鍵は認証デバイスのTPMやセキュアエレメントのような耐タンパ領域に保存• デメリット• 登録時に使用した認証デバイスがないと認証できない※認証デバイスの保持を認証要素の1つと見做せる側面もある9ユーザー 認証デバイス ブラウザ サーバーDB生体情報の検証承認ジェスチャ(生体情報)の提供• 生体情報• 生体情報
Copyright © Yoshikazu Nojima 2018フィッシング攻撃に対する効果• ユーザー認証ユーザー 認証デバイス ブラウザ サーバー承認ジェスチャ(指紋スキャン等)の実施• Credential Id• 認証デバイスデータ• RP Idのハッシュ• フラグ• カウンタ• 資格情報データ• 署名を送信• Credential Id• チャレンジ、ドメイン(RpId)その他• 認証デバイスデータ• RP Idのハッシュ• フラグ• カウンタ• 資格情報データ• 署名を送信• RP Idのハッシュ• チャレンジ、ドメイン(RpId)その他のハッシュRP固有秘密鍵でRpIdのハッシュ、フラグ、カウンタ、クライアントデータのハッシュを署名• チャレンジを送信ユーザー検証機能付き認証デバイスの場合耐タンパ領域• ローカル認証情報(生体情報等)を検証RP固有秘密鍵を読込ドメイン(RP Id)、署名その他の検証DBRP固有公開鍵の読込秘密鍵はRpId(≒ドメイン)毎に保存されており、フィッシング攻撃で他ドメインから認証要求を受けても秘密鍵は不正利用されない
Copyright © Yoshikazu Nojima 2018リスト型攻撃に対する効果• ユーザー認証ユーザー 認証デバイス ブラウザ サーバー承認ジェスチャ(指紋スキャン等)の実施• Credential Id• 認証デバイスデータ• RP Idのハッシュ• フラグ• カウンタ• 資格情報データ• 署名を送信• Credential Id• チャレンジ、ドメイン(RpId)その他• 認証デバイスデータ• RP Idのハッシュ• フラグ• カウンタ• 資格情報データ• 署名を送信• RP Idのハッシュ• チャレンジ、ドメイン(RpId)その他のハッシュRP固有秘密鍵でRpIdのハッシュ、フラグ、カウンタ、クライアントデータのハッシュを署名• チャレンジを送信ユーザー検証機能付き認証デバイスの場合耐タンパ領域• ローカル認証情報(生体情報等)を検証RP固有秘密鍵を読込ドメイン(RP Id)、署名その他の検証DBRP固有公開鍵の読込サーバー側に保存されるのはRP固有の公開鍵であり、他サイトで漏洩してもリスト型攻撃を受ける心配は不要
Copyright © Yoshikazu Nojima 2018モバイルデバイス対応近年のスマホで充実している、生体認証(指紋、顔認識)をローカル認証に活用することで、パスワードを打ち込む煩雑さからユーザーを開放し、離脱率を抑えることが期待12
Copyright © Yoshikazu Nojima 2018サーバーサイド観点でのWebAuthn13
Copyright © Yoshikazu Nojima 2018サービス/システムにWebAuthnを導入する場合、サーバーサイドで必要な対応14• ユーザー認証ユーザー 認証デバイス ブラウザ サーバー承認ジェスチャ(指紋スキャン等)の実施• Credential Id• 認証デバイスデータ• RP Idのハッシュ• フラグ• カウンタ• 資格情報データ• 署名を送信• Credential Id• チャレンジ、ドメイン(RpId)その他• 認証デバイスデータ• RP Idのハッシュ• フラグ• カウンタ• 資格情報データ• 署名を送信• RP Idのハッシュ• チャレンジ、ドメイン(RpId)その他のハッシュRP固有秘密鍵でRpIdのハッシュ、フラグ、カウンタ、クライアントデータのハッシュを署名ドメイン(RP Id)、署名チャレンジ、その他の検証• チャレンジを送信ユーザー検証機能付き認証デバイスの場合耐タンパ領域• ローカル認証情報(生体情報等)を検証RP固有秘密鍵を読込DBRP固有公開鍵の読込フロントエンドからcredentialIdやチャレンジ、署名などの認証情報を受信し、WebAuthn仕様で定められた検証を実施リプレイ攻撃防止用のチャレンジを送信
Copyright © Yoshikazu Nojima 2018WebAuthn4Jとは• WebAuthnの登録・認証メッセージ検証用ライブラリ• Java製、Apache2ライセンス• コミュニティベースの開発• https://github.com/webauthn4j/webauthn4j◼ 主な特徴• 全Attestation Statement対応• FIDO Allianceの準拠テストツールをパス• ポータビリティ• 依存ライブラリはJackson(JSON, CBOR処理)、Apache Kerby(ASN.1処理)、SLF4J(ログインタフェース)のみ。導入の障壁が少ない• テストサポート機能の充実• Keycloak向け拡張モジュール開発中• Spring Security拡張モジュール開発中15
Copyright © Yoshikazu Nojima 2018基本的な使用方法(登録)16// フロントエンドから受信したリクエスト、検証条件を詰めてコンテキストクラスを組立WebAuthnRegistrationContext registrationContext =new WebAuthnRegistrationContext(clientDataJSON, attestationObject, transports,serverProperty, userVerificationRequired);// Validatorの生成WebAuthnRegistrationContextValidator webAuthnRegistrationContextValidator =WebAuthnRegistrationContextValidator.createNonStrictRegistrationContextValidator();// 検証の実施WebAuthnRegistrationContextValidationResponse response =webAuthnRegistrationContextValidator.validate(registrationContext);// Authenticatorインスタンスの組立Authenticator authenticator =// アプリの要件にあわせ、Authenticatorインタフェースの独自実装利用可new AuthenticatorImpl(response.getAttestationObject().getAuthenticatorData().getAttestedCredentialData(),response.getAttestationObject().getAttestationStatement(),response.getAttestationObject().getAuthenticatorData().getSignCount());save(authenticator); // 認証に備え、永続化(方式はアプリケーション依存)
Copyright © Yoshikazu Nojima 2018// フロントエンドから受信したリクエスト、検証条件を詰めてコンテキストクラスを組立WebAuthnAuthenticationContext authenticationContext =new WebAuthnAuthenticationContext(credentialId, clientDataJSON, authenticatorData, signature,serverProperty, userVerificationRequired);// 永続化していたAuthenticatorの読込(方式はアプリケーション依存)Authenticator authenticator = load(credentialId);// Validatorの生成WebAuthnAuthenticationContextValidator webAuthnAuthenticationContextValidator =new WebAuthnAuthenticationContextValidator();// 検証の実施WebAuthnAuthenticationContextValidationResponse response =webAuthnAuthenticationContextValidator.validate(authenticationContext, authenticator);// カウンタの更新(方式はアプリケーション依存)updateCounter(response.getAuthenticatorData().getAttestedCredentialData().getCredentialId(),response.getAuthenticatorData().getSignCount());基本的な使用方法(認証)17
Copyright © Yoshikazu Nojima 2018テストサポート機能• WebAuthnによるログインのテストを自動化する場合、最大の問題は認証デバイスをどうするか• WebAuthn4Jではテストサポート用に認証デバイスのエミュレータを用意18// 認証デバイスエミュレータの接続されたクライアントエミュレータを準備private ClientPlatform clientPlatform = EmulatorUtil.createClientPlatform(new AndroidSafetyNetAuthenticator());@Testvoid validate_test(){String rpId = “example.com”;Challenge challenge = new DefaultChallenge();AuthenticatorSelectionCriteria authenticatorSelectionCriteria =new AuthenticatorSelectionCriteria(AuthenticatorAttachment.CROSS_PLATFORM, true, UserVerificationRequirement.REQUIRED);PublicKeyCredentialParameters publicKeyCredentialParameters = new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY,COSEAlgorithmIdentifier.ES256);PublicKeyCredentialUserEntity publicKeyCredentialUserEntity = new PublicKeyCredentialUserEntity();AuthenticationExtensionsClientInputs extensions = new AuthenticationExtensionsClientInputs<>();PublicKeyCredentialCreationOptions credentialCreationOptions= new PublicKeyCredentialCreationOptions(new PublicKeyCredentialRpEntity(rpId, “example.com”), publicKeyCredentialUserEntity, challenge,Collections.singletonList(publicKeyCredentialParameters), null, Collections.emptyList(),authenticatorSelectionCriteria, AttestationConveyancePreference.DIRECT, extensions);// エミュレータによるCredentialの生成PublicKeyCredential publicKeyCredential =clientPlatform.create(credentialCreationOptions);// 以下省略}
Copyright © Yoshikazu Nojima 2018WebAuthn4Jのスコープ (1/2)19• ユーザー認証ユーザー 認証デバイス ブラウザ サーバー承認ジェスチャ(指紋スキャン等)の実施• Credential Id• 認証デバイスデータ• RP Idのハッシュ• フラグ• カウンタ• 資格情報データ• 署名を送信• Credential Id• チャレンジ、ドメイン(RpId)その他• 認証デバイスデータ• RP Idのハッシュ• フラグ• カウンタ• 資格情報データ• 署名を送信• RP Idのハッシュ• チャレンジ、ドメイン(RpId)その他のハッシュRP固有秘密鍵でRpIdのハッシュ、フラグ、カウンタ、クライアントデータのハッシュを署名ドメイン(RP Id)、署名チャレンジ、その他の検証• チャレンジを送信ユーザー検証機能付き認証デバイスの場合耐タンパ領域• ローカル認証情報(生体情報等)を検証RP固有秘密鍵を読込DBRP固有公開鍵の読込スコープ外スコープ外スコープ• WebAuthn4JはWebAuthnのAttestation/Assertionの検証のみを実施する単機能ライブラリ• HTTPリクエストからのAttestation/Assertionの取出処理、DBへの永続化はスコープ外• Servlet APIなど、特定のAPIに依存しない為の設計
Copyright © Yoshikazu Nojima 2018WebAuthn4Jのスコープ (2/2)• ギャップへの対応• 認証フレームワークに合わせたアダプタライブラリを準備• Spring Security• Spring Security WebAuthnというExtensionを開発中• Spring Securityに則ったWebAuthn実装を提供• Spring SecurityのAuthenticationProviderインタフェースの実装• WebAuthnオプション提供用RESTエンドポイントServletFilter• 認証用ServletFilter• JavaConfig• 等々• Spring Security本体にPull Request中20
Copyright © Yoshikazu Nojima 2018まとめ• パスワード認証には限界がある• フィッシング攻撃対応• リスト型攻撃対応• モバイルデバイス対応• W3Cで新しい認証方式としてWeb Authentication仕様の策定が進められている• ローカル認証と公開鍵認証の組み合わせ• 生体情報をサーバーで保存する必要がなく安全性が高い• 仕様としてフィッシング攻撃対策、CSRF攻撃対策を盛込済• 主要ブラウザで実装が進行中• Edge/Chrome/Firefox/Safari• サーバーサイドの実装を補助する為、WebAuthn4JというJavaライブラリを開発• Spring SecurityやKeycloak向けにアダプタ開発中21