第13章 セキュアリモートパスワードプロトコル

Secure Remote Password (SRP) プロトコルは Internet Standards Working Group Request For Comments 2945 (RFC2945) で記述された公開鍵交換のハンドシェイクの実装です。RFC2945 の要約は次のように記載されています。
本書では Secure Remote Password (SRP) プロトコルとして知られる強固な暗号化方式のネットワーク認証メカニズムについて説明します。このメカニズムはユーザーが入力するパスワードを使用したセキュアな接続交渉に適している一方で、再使用可能なパスワードに従来関連付けられたセキュリティ問題を排除します。このシステムは認証プロセスでセキュアな鍵交換も実施し、セキュリティレイヤ (プライバシー / 整合性の保護) をセッション中に有効にします。信頼できる鍵サーバーや証明書インフラストラクチャは必要なく、クライアントは長期間鍵を保存、管理する必要はありません。SRP は既存のチャレンジレスポンス技術に対してセキュリティとデプロイメントの両方が持つ利点を提供し、セキュアなパスワード認証が必要な場合に理想的な完全互換品となります。
RFC2945 の完全な規則は http://www.rfc-editor.org/rfc.html を参照してください。SRP アルゴリズムとその歴史に関する追加情報は http://www-cs-students.stanford.edu/~tjw/srp/ を参照してください。
Diffie-HellmanRSA のようなアルゴリズムは公開鍵交換アルゴリズムとして知られています。公開鍵アルゴリズムの概念は、誰でも見ることができる公開キーと自分しか知らない秘密キーの 2 つのキーを持っているということです。誰かがあなたに暗号化した情報を送りたい場合、あなたの公開キーを使用してその情報を暗号化します。あなただけが秘密キーを使用してその情報を解読することができます。これを送信者と受信者が共有パスワードを知らなければならない従来の共通パスワードに基づく暗号化スキームと比べてみます。公開鍵アルゴリズムによりパスワードを共有する必要はなくなります。
JBossSX フレームワークには次の要素で構成される SRP 実装が含まれます。
  • どのクライアント / サーバープロトコルにも依存しない SRP ハンドシェイクプロトコルの実装
  • デフォルトのクライアント / サーバー SRP 実装としてのハンドシェイクプロトコルの RMI 実装
  • セキュアな方法でのクライアント認証を目的とする RMI 実装を使用するクライアント側 JAAS LoginModule 実装
  • RMI サーバー実装を管理する JMX MBean、この MBean により RMI サーバー実装が JMX フレームワークにプラグインでき、検証情報ストアの設定を外部化します。また、JBoss サーバー JNDI 名前空間にバインドされる認証キャッシュを確立します。
  • SRP JMX MBean により管理される認証キャッシュを使用するサーバー側 JAAS LoginModule 実装
図13.1「SRP クライアントサーバーフレームワークの JBossSX コンポーネント」 では SRP クライアント / サーバーフレームワークの JBossSX 実装に関連する主要コンポーネントについて説明します。
SRP クライアントサーバーフレームワークの JBossSX コンポーネント

図13.1 SRP クライアントサーバーフレームワークの JBossSX コンポーネント

クライアント側では SRP は org.jboss.security.srp.SRPServerInterface プロキシを通じて認証サーバーと通信するカスタムの JAAS LoginModule 実装として表されます。クライアントは org.jboss.security.srp.jaas.SRPLoginModule を含むログイン設定エントリを作成することで SRP を使用した認証を有効にします。このモジュールは次の設定オプションに対応します。
principalClassName
定数値で、org.jboss.security.srp.jaas.SRPPrincipal に設定します。
srpServerJndiName
SRP 認証サーバーと通信するために使用する SRPServerInterface オブジェクトの JNDI 名です。srpServerJndiNamesrpServerRmiUrl のオプションが両方とも指定されている場合は、srpServerJndiNamesrpServerRmiUrl より優先されます。
srpServerRmiUrl
SRP 認証サーバーと通信するために使用する SRPServerInterface プロキシの場所の RMI プロトコル URL 文字列です。
externalRandomA
クライアントの公開キー「A」のランダムコンポーネントがユーザーのコールバックから来るべきかを指定するフラグです。これを使用してハードウェアトークンからの強固な暗号式の乱数を入力します。true に設定するとこの機能が有効になります。
hasAuxChallenge
サーバーが検証する追加チャレンジとして文字列がサーバーに送られるかを指定するフラグです。クライアントセッションが暗号化方式に対応している場合は、セッション秘密キーと javax.crypto.SealedObject として送られたチャレンジオブジェクトを使用して一時的な暗号化方式が作成されます。true に設定するとこの機能は有効になります。
multipleSessions
特定のクライアントが複数の SRP ログインセッションをアクティブにするかを指定するフラグです。true に設定するとこの機能は有効になります。
上記記載のオプションのいずれにも一致しないその他の渡されたオプションは InitialContext コンストラクタに渡された環境が使用する JNDI プロパティとして処理されます。これは SRP サーバーインターフェースがデフォルトの InitialContext より使用できない場合に役立ちます。
SRP 認証資格情報をセキュリティ Java EE コンポーネントへのアクセス検証に使用できるように、SRPLoginModule と標準 ClientLoginModule を設定する必要があります。ログイン設定の例は 例13.1「ログイン設定エントリ」 に記載されています。

例13.1 ログイン設定エントリ

srp {
    org.jboss.security.srp.jaas.SRPLoginModule required
    srpServerJndiName="SRPServerInterface"
    ;
            
    org.jboss.security.ClientLoginModule required
    password-stacking="useFirstPass"
    ;
};
JBoss サーバー側には、SRP サーバーを集団的に構成するオブジェクトを管理する MBean が 2 つあります。主要なサービスは org.jboss.security.srp.SRPService MBean です。もう 1 つの MBean は org.jboss.security.srp.SRPVerifierStoreService です。
org.jboss.security.srp.SRPService の役割は、SRPServerInterface の RMI アクセス可能なバージョンを公開するだけでなく SRP 認証セッションキャッシュを更新することです。
設定可能な SRPService MBean 属性として以下が挙げられます。
JndiName
SRPServerInterface プロキシが使用可能であるべき場所の名前を指定します。これは SRPService がシリアル化可能な動的プロキシを SRPServerInterface にバインドする場所です。デフォルト値は srp/SRPServerInterface です。
VerifierSourceJndiName
SRPService が使用する必要がある SRPVerifierSource 実装の名前を指定します。ソースの JNDI 名は srp/DefaultVerifierSource にデフォルト設定されます。
AuthenticationCacheJndiName
認証情報をキャッシュするために使用する org.jboss.util.CachePolicy 認証実装がバインドされる名前を指定します。SRP セッションキャッシュはこのバインディングを通じて使用可能になります。認証 JNDI キャッシュは srp/AuthenticationCache にデフォルト設定されます。
ServerPort
SRPRemoteServerInterface の RMI ポートです。デフォルト値は 10099 です。
ClientSocketFactory
SRPServerInterface のエクスポート中に使用されるオプションのカスタム java.rmi.server.RMIClientSocketFactory 実装クラス名です。デフォルト値は RMIClientSocketFactory です。
ServerSocketFactory
SRPServerInterface のエクスポート中に使用されるオプションのカスタム java.rmi.server.RMIServerSocketFactory 実装クラス名です。デフォルト値は RMIServerSocketFactory です。
AuthenticationCacheTimeout
キャッシュポリシーのタイムアウト (秒単位) です。デフォルト値は 1800秒 (30 分) です。
AuthenticationCacheResolution
時間制限されたキャッシュポリシーのリゾリューションを指定します (秒単位)。これはタイムアウトのチェック間隔を制御します。デフォルト値は 60秒 (1 分) です。
RequireAuxChallenge
クライアントが検証フェーズの一部として補助チャレンジを与える必要があるか設定します。これでクライアントが使用する SRPLoginModule 設定によって useAuxChallenge オプションを有効にする必要があるか制御できます。
OverwriteSessions
既存セッションに対して成功するユーザー認証が現在のセッションを上書きすべきか指定します。クライアントが複数セッションをユーザーモードごとに有効にしていない場合は、サーバー SRP セッションキャッシュの動作を制御します。false に設定すると、2 番目のユーザー認証の試行は成功します。ただし、それによって生じる SRP セッションは前の SRP セッション状態を上書きしません。デフォルト値は false です。
VerifierStoreJndiName
JNDI を通じて提供され使用可能となる必要がある SRP パスワード情報ストア実装の場所を指定します。
org.jboss.security.srp.SRPVerifierStoreService は、固定ストアとしてシリアル化されたオブジェクトのファイルを使用する SRPVerifierStore インターフェースの実装をバインドする MBean サービスの一例です。実稼働環境には現実的ではありませんが、SRP プロトコルのテストが可能で、SRPVerifierStore サービスに要件の一例を提供します。
設定可能な SRPVerifierStoreService MBean 属性として以下が挙げられます。
JndiName
SRPVerifierStore 実装が使用可能であるべき場所の JNDI 名です。指定されていない場合は、srp/DefaultVerifierSource にデフォルト設定されます。
StoreFile
ユーザーパスワードベリファイアのシリアル化されたオブジェクトストアファイルの場所です。これはクラスパスにある URL またはリソース名のいずれかになります。指定されていない場合は、SRPVerifierStore.ser にデフォルト設定されます。
SRPVerifierStoreService MBean はユーザーの追加および削除に対する addUserdelUser 動作にも対応します。シグネチャは以下のとおりです。
public void addUser(String username, String password) throws IOException;
public void delUser(String username) throws IOException;
こうしたサービスの設定例は 例13.2「SRPVerifierStore インターフェース」 に記載されています。

13.1. アルゴリズムの理解

SRP アルゴリズムの利点は、セキュアな通信チャンネルがなくてもシンプルなテキストパスワードを使用してクライアントとサーバーの相互認証が可能であることです。

注記

SRP アルゴリズムとその歴史に関する追加情報は http://srp.stanford.edu/ に記載されています。
認証を完了するためには 6 つのステップを実行します。
  1. クライアント側 SRPLoginModule がネーミングサービスからリモート認証サーバーの SRPServerInterface インスタンスを取得します。
  2. 次に、クライアント側 SRPLoginModule はログインを試行しているユーザー名に関連付けられた SRP パラメータを要求します。ユーザーパスワードが最初に SRP アルゴリズムを使用した検証形式に変換されるときに選択される必要がある SRP アルゴリズムに含まれるパラメータは多くあります。パラメータをハードコードするのではなく (最小限のセキュリティリスクで実行可能)、JBossSX 実装によりユーザーは交換プロトコルの一部としてこの情報を取得できます。getSRPParameters(username) 呼び出しは特定のユーザー名の SRP パラメータを取得します。
  3. クライアント側 SRPLoginModule はログインユーザー名、クリアテキストのパスワード、ステップ 2 で取得した SRP パラメータを使用して SRPClientSession オブジェクトを作成することで SRP セッションを開始します。次に、クライアントは秘密 SRP セッションキーを構築するために使用される乱数を作成します。そして SRPServerInterface.init メソッドを呼び出すことで SRP セッションのサーバー側を初期化し、ユーザー名とクライアントが生成した乱数 A を渡します。サーバーは独自の乱数 B を返します。このステップは公開キーの交換に相当します。
  4. クライアント側 SRPLoginModule は前のメッセージ交換の結果として生成された秘密 SRP セッションキーを取得します。これはログイン Subject で秘密の資格情報として保存されます。ステップ 4 でのサーバーのチャレンジレスポンス M2SRPClientSession.verify メソッドを呼び出すことで検証されます。これが成功すると、クライアントからサーバー、およびサーバーからクライアントへの相互認証が完了します。次に、クライアント側 SRPLoginModule はサーバー乱数 B を引数として渡している SRPClientSession.response メソッドを呼び出すことでサーバーへのチャレンジ M1 を作成します。このチャレンジは SRPServerInterface.verify メソッドによりサーバーに送られ、サーバーのレスポンスは M2 として保存されます。このステップはチャレンジの交換に相当します。この時点で、サーバーはユーザーがそのユーザー本人であることを確かめます。
  5. クライアント側 SRPLoginModule はログインユーザー名と M1 チャレンジを LoginModule sharedState マップに保存します。これが標準 JBoss ClientLoginModule により Principal の名前と資格情報として使用されます。M1 チャレンジは、Java EE コンポーネントのすべてのメソッド呼び出しでアイデンティティの証明としてパスワードの代わりに使用されます。M1 チャレンジは、SRP セッションと関連付けられた強固な暗号化方式のハッシュです。第 3 者による傍受はユーザーのパスワードを取得するためには使用できません。
  6. この認証プロトコルの最後で、SRPServerSession は SRPCacheLoginModule によって後続して使用できるよう SRPService 認証キャッシュに配置されました。
SRP には多くの興味深いプロパティがありますが、今もなお JBossSX フレームワークの発展中のコンポーネントであり、認識しておくべき制約が数点あります。注意すべき点は以下のとおりです。
  • 認証が実行されたところで、JBoss がメソッドのトランスポートプロトコルをコンポーネントコンテナから分離する方法によって、ユーザーは SRP M1 チャレンジをスヌープして、効果的にチャレンジを使用して関連付けられたユーザー名として要求を行うことが可能になります。SRP セッションキーを使用してチャレンジを暗号化することにより、カスタムのインターセプタを使用してこの問題を防止できます。
  • SRPService は設定可能な期間が過ぎた後にタイムアウトする SRP セッションのキャッシュを管理します。タイムアウトした時点で、SRP 認証資格情報を透過的に再交渉するメカニズムは現在ないため、Java EE コンポーネントの後続アクセスはすべて失敗します。認証キャッシュのタイムアウトをかなり長く設定するか、失敗したらコードで再認証を行う必要があります。

    注記

    SRPService は最大で 2,147,483,647 秒、または約 68 年間のタイムアウトに対応します。
  • デフォルトでは特定のユーザー名に対して SRP セッションは 1 つだけです。交渉される SRP セッションはクライアントとサーバー間の暗号化と復号化に使用できる秘密セッションキーを生成するため、セッションはステートフルとして扱われます。JBoss はユーザーごとに複数の SRP セッションをサポートしますが、1 つのセッションキーでデータを暗号化し、別のセッションキーで復号化することはできません。
Java EE コンポーネント呼び出しにエンドツーエンド SRP 認証を使用するには、コンポーネントが org.jboss.security.srp.jaas.SRPCacheLoginModule を使用するのにセキュアであるセキュリティドメインを設定する必要があります。SRPCacheLoginModule には SRP 認証 CachePolicy インスタンスの JNDI 場所を設定する cacheJndiName という名前の単一の設定オプションがあります。これは SRPService MBean の AuthenticationCacheJndiName 属性値と対応しなければなりません。
SRPCacheLoginModule は、認証キャッシュの SRPServerSession オブジェクトからクライアントチャレンジを取得し、これをユーザーの資格情報として渡されるチャレンジと比較することでユーザーの資格情報を認証します。図13.2「SRP セッションキャッシュを使用した SRPCacheLoginModule」 では SRPCacheLoginModule.login メソッド実装の動作を図解しています。
SRP セッションキャッシュを使用した SRPCacheLoginModule

図13.2 SRP セッションキャッシュを使用した SRPCacheLoginModule