- IAM 入門
- 認証(AuthN)とは?
認証(AuthN)とは?
認証とは、ユーザー(または、マシン間通信の場合はクライアントやサービス)が、保護されたリソースにアクセスする前に、その身元(アイデンティティ)を確認するプロセスです。つまり、「あなたは誰ですか?」という根本的な問いに答えるものです。
アプリケーションがアクセスを許可する前に、まずアクセスを要求している主体が、主張するとおりの人物であることを確認する必要があります。認証はアクセス制御の最初のステップであり、常に認可に先立って行われます。ある主体が何へアクセスできるかを判断する前に、その主体のアイデンティティを検証しなければいけません。
ユーザーやサービスは、認証情報や認証要素を提示することで自身のアイデンティティを証明します。システムは、それらの情報を保存されている記録や信頼できる外部のアイデンティティプロバイダー(IdP)と照合し、正当性を検証します。たとえば、開発者がリモートサーバーにSecure Shell(SSH)キーを提示するケースを考えてみてください。サーバーはそのキーの署名を検証し、クライアントのアイデンティティを確認します。
認証が重要な理由:認証は、アクセス権を付与する前に主体のアイデンティティを確立するための仕組みです。アイデンティティが確認されていなければ、アプリケーションは認可ポリシーの適用や機密データの保護、監査証跡の維持ができません。
中心となる認証要素
認証要素は、大きく3つのカテゴリに分類されます。多要素認証(MFA)の本質的なセキュリティ上の強みは、異なるカテゴリの要素を2つ以上組み合わせることから生じます。
| 要素のカテゴリー | 証明の仕組み | 一般的な例 |
|---|---|---|
| 知識情報(知っていること) | ユーザーが記憶している秘密 | パスワード、個人識別番号(PIN)、パスフレーズ |
| 所有情報(持っているもの) | ユーザーが管理している物理的なデバイスやトークン | スマートフォン(TOTPやプッシュ通知用)、ハードウェアセキュリティキー、FIDO2/WebAuthnキー、スマートカード |
| 生体情報(ユーザー自身の属性) | ユーザー固有の検証可能な生体的特徴 | 指紋、顔認証、虹彩スキャン |
最新の認証方式
基本的なパスワード認証以外にも、さまざまな認証方式が存在します。それぞれにセキュリティと利便性の面で異なるトレードオフがあります。
パスワードベースの認証
パスワードベースの認証は、最も広く利用されている方式です。ユーザーが認証情報を入力すると、安全に保存されている記録と照合されます。
パスワードをセキュアに保存するには、Argon2、bcrypt、PBKDF2のような、適応的で計算コストの高いハッシュアルゴリズムを使用し、さらに各パスワードに固有のソルトを付与する必要があります(NIST SP 800-63B)。MD5やSHA-1のような旧式のアルゴリズムを使用してはいけません。
パスワード認証には次のような脆弱性があります。
- フィッシングやマルウェアによって直接パスワードが盗まれる可能性がある
- 複数のサイトで同じパスワードを使い回している場合、1つのサービスで発生した情報漏えいによって複数のアカウントが侵害される可能性がある
- ユーザーが覚えやすさを優先して、推測されやすい弱いパスワードを設定してしまう
- 過去の情報漏えいで流出したパスワードのリストを利用するクレデンシャルスタッフィングの標的となる
そのため本番システムでは、パスワードのみを用いた認証は十分とは言えません。
Multi-factor Authentication
MFAでは、アクセスが許可される前に、異なるカテゴリに属する2つ以上の異なる要素を用いてアイデンティティ確認を行うことが求められます。
たとえば、ユーザーはパスワードを入力した後、認証アプリが生成したコードの入力や、プッシュ通知による承認、または生体認証など、第2の認証要素を提示する必要があります。攻撃者は両方の要素を必要とするため、認証情報の窃取を利用した攻撃の大半を防ぐことができます。なお、SMSやEメールのコードは、プッシュ通知やFIDO2対応のハードウェア認証器と比べると、セキュリティ面で劣ります。
パスキー(FIDO2/WebAuthn)
パスキーは、パスワードの代わりにFIDO2認証情報を使用する認証方式です。フィッシング耐性を持つよう設計されており、FIDO2プロトコル(WebAuthnとCTAP)を基盤としています。
パスキーは公開鍵暗号方式を利用します。登録時に、デバイス上で公開鍵と秘密鍵のペアが生成されます。秘密鍵はデバイスに暗号学的に結び付けられ、デバイスのセキュア領域から持ち出せないよう設計されています。一方、公開鍵はサービス側に登録され、デバイスの真正性を証明します。
ログイン時には、デバイスが暗号学的チャレンジに対して電子署名を生成します。この署名は、それを要求した特定のドメインでのみ有効です。そのため、フィッシングサイトは、たとえリアルタイム型のフィッシングプロキシを利用したとしても、この署名を傍受して再利用することはできません。パスキーは、秘密鍵がデバイス外に一切持ち出されず、生体認証やデバイスのPINによってのみ解除できるため、フィッシング耐性のあるMFAレベルのセキュリティを提供します。また、ポリシーによってデバイスへの固定が求められていない限り、パスキーはプラットフォームの認証情報管理機能(iCloudキーチェーンなど)を通じて複数のデバイス間で同期できます。
フェデレーションアイデンティティとソーシャルログイン
フェデレーションアイデンティティでは、信頼できる外部のIdPに認証を委任します。
OpenID Connect(OIDC):ユーザーはIdPで認証を行い、アプリケーションは暗号学的に署名されたIDトークンを受け取ります。このIDトークンには、Eメールアドレスや氏名など、検証済みのアイデンティティ情報(クレーム)が含まれており、アプリケーションがユーザーの認証情報を直接扱う必要はありません。
この仕組みによって、認証情報を保存する必要がなくなるため、オンボーディング時の負担を軽減できるほか、IdPが提供するセキュリティ基盤を活用できます。また、エンタープライズ環境では、シングルサインオン(SSO)を実現するためのプロトコルとして、SAML 2.0も広く利用されています。
シングルサインオン
SSOを利用すると、ユーザーは中央のIdPで一度認証を行うだけで、認証情報を再入力しなくても複数のアプリケーションにアクセスできるようになります。
SSOでは、SAML 2.0やOpenID Connectなどのプロトコルが利用されます。ユーザーがログインすると、IdPはセキュリティトークンを発行し、ログインセッションを維持します。各アプリケーションはそのセッションを信頼し、新たなログインを要求せずにアクセスを許可します。多くの組織では、SSOセッションの有効期間を一般的な勤務時間のパターンに合わせて設定しています。ただし、実際のセッション有効期間は、セキュリティポリシー、リスクシグナル、保証レベルの要件などによって決まります。
認証プロトコルとトークンフロー
最新の認証では、専用の認可サーバーまたはIdPが、標準規格に準拠したトークンを発行し、そのトークンを利用してアクセス制御を行います。
OpenID Connect(OIDC)とOAuth 2.0
両者の違いは次のとおりです。
OAuth 2.0は、アクセス権の委任を目的とした認可フレームワークです。エンドユーザーのアイデンティティを検証するための標準化されたトークンやプロトコルは定義されていません。
OpenID Connect(OIDC)は、OAuth 2.0の上に構築されたアイデンティティレイヤーです。OIDCでは、IdPから発行されるIDトークンを利用してユーザーのアイデンティティを検証するための標準化された仕組みが提供されます。IDトークンには、認証済みであることを示す署名付きのクレームが含まれています。
両者は互いに補完し合う関係にあります。OIDCは認証(ユーザーのアイデンティティの証明)を担当し、OAuth 2.0は認可(APIへのアクセス権限の付与)を担当します。
PKCEを使用したAuthorization Code Flow
PKCE(Proof Key for Code Exchange)を使用したAuthorization Code Flow(認可コードフロー)は、Webアプリケーションとモバイルアプリケーションで推奨される認証フローです。PKCEは、認可コード横取り攻撃を防ぎます。
仕組み:アプリケーションはまず、十分なランダム性を持つコードベリファイア(code verifier)と、そのハッシュ値であるコードチャレンジ(code challenge)を生成します。その後、ユーザーが認可サーバーで認証を行うと、サーバーは有効期間が短い認可コード(数分程度で失効)を発行します。認可サーバーはコードベリファイアとコードチャレンジが一致することを確認したうえで、トークンを発行します。
認可サーバーは、クライアント向けに認証クレームを含むIDトークンを発行し、API呼び出し用にアクセストークンを発行します。さらに、アプリケーションがoffline_accessスコープを通じてオフラインアクセスを要求した場合、サーバーはリフレッシュトークンも発行します。リフレッシュトークンを利用すると、再認証なしで新しいアクセストークンを取得できます。
トークンベース認証とJWT
APIはユーザーを直接認証するのではなく、トークンを検証します。この方式では、APIがデータベースにセッション情報を保持する必要がないため、認証をステートレスかつスケーラブルに実現できます。
JSON Web Token(JWT)は、最も広く利用されているトークン形式です。JWTには認証や認可に必要なクレームがすべて含まれているため、APIはステートレスにトークンを検証できます。アーキテクチャによっては完全にステートレスな構成を採用する場合もありますが、セキュリティ要件に応じて、追加のチェック(ユーザーのステータス確認やトークン失効確認など)を行う場合もあります。
クライアントがAPIを呼び出す際には、アクセストークンをAuthorization: Bearer <token>ヘッダーに含めて送信します。APIはリクエストごとにJWTを検証して、トークンが正当なものか、有効期限内か、そのアプリケーション向けに発行されたものかという点を確認する必要があります。
- トークンの構造がJWTの形式に従っていることを確認する(
header.payload.signature) - 適切な鍵を使用して署名の整合性をチェックし、トークンが改ざんされていないことを確認する
- 有効期限を確認するために
expクレームを検証し、必要に応じてnbf(Not Before)やiat(Issued At)クレームも確認して、無効なトークンや有効化前のトークンを拒否する - 発行者を確認するために、
issクレームの値が、信頼できるIdPと一致することを確認する - 対象者を確認するために
aud(Audience)クレームが自身のアプリケーションと一致することを確認する - 非対称署名アルゴリズムを優先的に使用(
RS256やES256)し、共有シークレットを保持することなく公開鍵でトークンを検証できるようにする。HS256は完全に信頼できる環境でのみ使用する noneアルゴリズムは署名検証を回避できてしまうため、決して受け入れない
人間以外のアイデンティティの認証
API、サービス、マシン間の通信では、人間による操作を前提としない、暗号技術に基づくアイデンティティの検証が必要になります。
クライアントクレデンシャルフロー:サーバー間通信のためのOAuth 2.0フローです。サービスは、client_idとclient_secretを使用して認証を行います。これらは機密性の高い認証情報として保護する必要があり、ソースコード管理システムにコミットしてはいけません。認可サーバーは認証情報を検証した後、アクセストークンを発行します。
非対称鍵ペア:サービスは、非対称鍵ペアを利用してクライアント認証を行うこともできます。この方式では、クライアントは署名付きJWTアサーション(RFC 7523)を提示し、認可サーバーは登録済みの公開鍵を使用して署名を検証するため、共有シークレットを使用しません。
ワークロードアイデンティティ:クラウドプラットフォームが実行中のサービスの正当性を暗号学的に保証し、有効期間の非常に短い認証情報を動的に発行します。そのため、長期間利用される固定的なシークレットを保持する必要がなくなります。
セキュアな認証のためのベストプラクティス
セキュアなアプリケーションを構築するためには、最新のアイデンティティ管理に関するベストプラクティスに従うことが重要です。
| セキュリティ上の考慮事項 | 開発者への推奨事項 |
|---|---|
| フィッシング対策 | 認証情報の窃取に対する最も強力な防御策として、他の認証要素(SMSやTOTPなど)よりも、FIDO2/WebAuthnのパスキーを優先的に採用する。 |
| 認証フローのセキュリティ | すべてのクライアントで、PKCEを使用したAuthorization Code Flowを実装する。 |
| トークンの有効期間 | トークンが盗まれた場合に悪用可能な時間を最小限に抑えるため、有効期間の短いアクセストークンを使用する(例:15~60分)。また、シームレスに更新するために、リフレッシュトークンローテーションを利用する。 |
| トークンの保存 | クロスサイトスクリプティング(XSS)のリスクがあるため、アクセストークンやリフレッシュトークンをlocalStorageやsessionStorageに保存しない。ブラウザアプリでは、SPA向けのSecure属性とHttpOnly属性を付与したCookieを利用するか、トークンをメモリ上のみに保持し、localStorageやsessionStorageに保存しない。従来型のWebアプリでは、HttpOnly属性とSecure属性を付与したCookieを使用したサーバーサイドセッションを採用する。 |
| APIにおけるトークン検証 | 保護対象APIへのリクエストごとにJWTの署名を検証する。この検証を省略すると、重大なセキュリティ脆弱性につながる。 |
| 認証情報の保護 | 適応的ハッシュアルゴリズム(Argon2またはbcrypt)を使用してパスワードを適切に管理し、ブルートフォース攻撃やクレデンシャルスタッフィング攻撃を防ぐためにレート制限を実装する。また、漏えいしたパスワードの検出機能を利用して、侵害が確認されている認証情報を自動的に検出する。 |
認証(AuthN)に関するよくある質問
認証と認可の違いは何ですか?
認証(AuthN)では、ユーザーのアイデンティティを確認します。つまり、「あなたは誰ですか?」という問いに答えるものです。一方、認可(AuthZ)は、そのユーザーに許可されている操作やアクセス範囲を決定します。つまり、「あなたは何を行うことができますか?」という問いに答えます。認証は認可よりも先に行われます。システムが権限を確認する前に、まず自身のアイデンティティを証明しなければいけません。
なぜパスワードだけによる認証は、もはや安全ではないのですか?
パスワードは、セキュリティ上の最も大きな弱点です。フィッシング攻撃やクレデンシャルスタッフィング攻撃を受けやすいためです。現在のセキュリティ要件を満たすには、MFAを追加するか、パスキーのようなフィッシング耐性のあるパスワードレスな認証方式へ移行する必要があります。
現在利用できる最もセキュアな認証方式は何ですか?
現時点では、FIDO2/WebAuthnに基づくパスキーが最もセキュアな認証方式とされています。パスキーは公開鍵暗号方式を利用しており、オリジンに紐付けられています。認証情報は特定のドメインでしか利用できないため、攻撃者がそれを盗み取っても別のサイトで再利用できません。
OpenID Connect(OIDC)は認証でどのような役割を果たしますか?
OIDCは、OAuth 2.0にアイデンティティ検証機能を追加します。OIDCでは、IDトークンと呼ばれるJSON Web Token(JWT)が導入されています。IDトークンは、ユーザーのアイデンティティを証明する、標準化された検証可能な情報を提供します。OAuth 2.0単体では、これは実現できません。
JWTアクセストークンが盗まれた場合の主なセキュリティリスクは何ですか?
アクセストークンが盗まれると、攻撃者はそのトークンの有効期限が切れるまで、ユーザーになりすますことができます。JWTはステートレスであり、即座に失効させることが難しいため、被害を最小限に抑えるには、有効期間の非常に短いアクセストークン(15~60分程度)とリフレッシュトークンローテーションを利用することが推奨されます。リフレッシュトークンローテーションでは、トークンが使用されるたびにサーバーが以前のトークンを無効化するため、トークンの盗難を即座に検知できます。
パスワードレス認証はどのように機能しますか?
パスワードレス認証では、秘密情報を記憶する必要がありません。代わりに、所持情報(例:デバイスバウンドパスキーやハードウェアキー)や生体情報(例:生体認証)を利用して、ユーザーのアイデンティティをセキュアに検証します。
詳細をご覧になりたいですか?
認証はアプリケーションセキュリティの基盤ですが、それは出発点に過ぎません。包括的なセキュリティモデルを構築するためには、アイデンティティの確認後にアクセスがどのように制御されるのかを理解する必要があります。アイデンティティとアクセス管理に関連するその他のトピックについては、「IAM入門」シリーズをご覧ください。
これらの資料は一般的な情報提供のみを目的としています。本資料の利用者は、自身の責任において、自身の専門アドバイザーからセキュリティ、プライバシー、コンプライアンス、またはビジネスに関する助言を得るものとし、本資料に記載された情報のみに依存すべきではありません。
Table of contents
Quick assessment
パスワードレス認証を利用する理由は?(当てはまるものをすべてお選びください)
Quick assessment
認証システムにおける「所有物」の例は何ですか?(当てはまるものをすべてお選びください)