CIFS認証プロトコル仕様 Paul J. Leach Microsoft Preliminary Draft - do not cite Author's draft: 4 これは、CIFS 認証プロトコルの新しい仕様についての提案を含む草稿の前段 階のドキュメントであり、レビューの便を考慮して、単体のドキュメントとし て提供しているものである。この実装が受け入れられた場合は、CIFS の仕様 の将来の版に取り込まれることになろう (この仕様は、通知なしに変更される ことがあり、Microsoft Corporation が product commitment を行なったもの ではない)。 本文書は2つのセクションからなっている。一つは認証プロトコルそのものに ついてであり、もう一つは、このプロトコルがどのようにネゴシエーションで 用いられ、プロトコルのメッセージが CIFS のリクエストおよびレスポンスに おいて転送されるかについてである。 1. CIFS 認証プロトコル このセクションでは、CIFS のセッションおよびメッセージ認証プロトコルに ついて定義する。セッション認証は、ユーザのパスワードについての共通の情 報の存在に基づいたチャレンジアンドレスポンスプロトコルにより行なわれる。 メッセージ認証は各メッセージにメッセージ認証コード(MAC)を付加すること により行なわれる。 1.1 概要 一つの基本認証スキームには、幾つかの種類がある。サーバのリソースに対す る認証されたアクセスを行なうために、サーバはクライアントに対して、クラ イアントがパスワードを知っていることを確認するために、「チャレンジ」を 送信する。ユーザのパスワードから算出される168ビットのセッションキーを 用いてチャレンジ(および場合によってはクライアントが選択した一時的な値) を暗号化することによって「レスポンス」が生成される。レスポンスもしくは その一部とクライアント側の一時的な値はサーバに返却され、サーバは同様の 計算を行なうことでレスポンスの正当性を確認する。クライアントとサーバは 次のセクションで説明する機構のいずれを確認に用いるかをネゴシエートする (ダウングレードアタックを許可しないように、注意深く行なう)。 ここでは、CIFS サーバがクライアントのパスワードを保持しているかのよう に、セッション認証プロトコルについて説明しているが、実装によっては、パ スワードはキー配布サーバ(KDS)が保持しており、この仕様の範囲外のプロト コルによりサーバに配布し、本プロトコルで必要な処理を行なうことを可能と している場合も考えられる。 一度セッションが認証されたら、以降のメッセージはメッセージ毎に MAC を 算出してメッセージに付加することにより認証することができる。利用される MAC は、セッションキーより算出された「MACキー」とサーバのチャレンジに 対するレスポンスを使用する IPSec [RFC 1828] で使われているものに類似し た keyed MD5 構造体である。この MAC によりメッセージ本文とシーケンス番 号の両方がリプレイ攻撃から保護される。 Paul Leach Page 1 03/25/97 Preliminary CIFS AuthenticationMay change without notice 1.2 定義 ここで E(K, D) DES block mode 暗号化関数 [FIPS 81] を示す。これは、7バイトのキー (K) と 8 バイトのデータブロック (D) を引数にとり、8 バイトの暗号化さ れたデータブロックを値として返却する。 Ex(K,D) より長いキーとデータブロックをとる拡張された DES を示す。暗号化され るデータが 8 バイトより長い場合、暗号化関数を先頭から順に 8 バイトず つ区切ったデータに対して実行した上で結果を連結する。キーが 7 バイト よりも長い場合、8 バイトの各データに対して、最初にキーの先頭 7 バイ トを使った暗号化が行なわれ、ついで次の 7 バイトを使った暗号化が行な われていき、各々の結果は連結される。例えば、16バイトの D0D1 という値 を 14 バイトのキー K0K1 で暗号化した場合は、以下のようになる。 Ex(K0K1,D0D1) = concat(E(K0,D0),E(K0,D1),E(K1,D0),E(K1,D1)) concat(A, B, Z) は、バイト文字列 A, B, Z を連結した結果となる。 head(S, N) バイト文字列 S の先頭 N バイトを示す。 swab(S) S の各バイトのビット順を反転させることによって得られるバイト文字列を 示す。S が 0x37 という値の 1 バイト文字列の場合、swab(S) は 0xEC になる。 zeros(N) 値が 0 (ゼロ)である長さ N のバイト文字列を示す。 ones(N) 全てのバイトが 255 の値である長さ N のバイト文字列を示す。 xor(A, B) A および B の各バイトの論理「xor」を行なうことによって得られるバイト 文字列を示す。 and(A, B) A および B の各バイトの論理「and」を行なうことによって得られるバイト 文字列を示す。 substr(S, A, B) 文字列 S の A 番目のバイトから N バイト取得することによって得られる 長さ N のバイト文字列を示す。最初のバイトは 0 番目となる。例えば、S が「NONCE」という文字列の場合、substr(S, 0, 2) は「NO」となる。 Paul Leach Page 2 03/25/97 Preliminary CIFS AuthenticationMay change without notice 1.3 セッションキー セッション認証プロトコルは、各 dialect に相当するが、セッションキーの 算出は dialect および以下で説明する認証方式のネゴシエーションによって 異なる。 1.3.1 NT セッションキー セッションキー S21 および MAC キーの一部 S16 の算出は以下のとおり: S16 = MD4(U(PN)) S21 = concat(S16, zeros(5)) ここで o PN は、大文字小文字を区別し、長さの制限のない、クリアテキストの ユーザのパスワードを含む文字列 o U(x) は ASCII 文字列「x」を Unicode に変換した文字列 o MD4(x) はバイト文字列「x」から生成した 16 バイトの MD4 メッセー ジダイジェスト [RFC 1320] 1.3.2 LM セッションキー セッションキー S21 および MAC キーの一部 S16 の算出は以下のとおり: S16X = Ex(swab(P14),N8) S21 = concat(S16X, zeros(5)) S16 = concat(head(S16X, 8), zeros(8)) ここで o P14 は、大文字のみで、14 バイト長の、スペースでパディングされた、 クリアテキストのユーザのパスワードを含む文字列 o N8 は、リクエストの際に Microsoft から提供される 8 バイトの文字 列 (訳注: これが有名な? KGS!@#$% である) 1.4 セッション認証プロトコル セッション認証プロトコルは、以下の順に処理が行なわれる: o サーバは 8 バイトの一意なチャレンジ C8 (これは以前に使われたことがな く、再利用されることもない「一時的な値」である) を選択し、それをクラ イアントに送信する。 o クライアントは以下の計算を行なう RN = Ex(S21,C8) Paul Leach Page 3 03/25/97 Preliminary CIFS AuthenticationMay change without notice o クライアントは 24 バイトのレスポンス RN をサーバに送信する。 o サーバは上記のように RN を計算し、受信したレスポンス中の RN の値と計 算した値とを比較する。両者が等しい場合、クライアントは認証される。 1.6 メッセージ認証コード MAC は keyed MD5 構造体である: MAC(K, text) = head(MD5(concat(K, text)), 8) ここで: MD5 は、MD5 hash 関数である。RFC 1321 を参照のこと K は、キーである。 text は、MAC を計算するために使われるメッセージである。 keyed MD5 の IPSec への適用例については、RFC 1828 を参照のこと。適切に 用いられないと、keyed MD5 は MAC と同様の脆弱性を持ってしまう。MD5 の ような反復ハッシュ(iterative hash)は、 message extension attack を受け て、解読されやすい [Kal 95] 。この構造体に上記の脆弱性の影響はない。こ れは、使われるメッセージが message extension attack を受けないだけの長 さを持っているためである。また圧縮関数が常に 2 回行なわれる上、ハッシュ の先頭 64 ビットのみが使われる。これにより既知の解読テクニックの適用を 妨げられる。 1.7 MAC キー MAC キーは以下のようにして計算される: K = concat(S16, RN) ここで S16 と RN は前述したとおりである。 K は、RN の長さによるが、40 もしくは 44 ビット長になる。 1.8 メッセージ認証プロトコル 一度セッションが認証されると、各メッセージも同様に認証することが可能と なる。これにより仲介者攻撃、リプレイ攻撃、能動的なメッセージの改竄攻撃 (以下のセキュリティ上の懸案事項を参照のこと)が防止される。 ここで SN Paul Leach Page 4 03/25/97 Preliminary CIFS AuthenticationMay change without notice は、要求されたシーケンス番号である。初期値は 0 である。クライアント とサーバの双方でコネクション毎に1つの SN を共有する。 RSN は、リクエストに対するレスポンスで期待されるシーケンス番号である。 req_msg は、リクエストのメッセージである。 rsp_msg は、レスポンスのメッセージである。 SN は、論理的に、以下のセクションで記述する認証されたメッセージトラン スポートの各メッセージに含まれ、同じセクションで記述されているように、 MAC の計算の対象となる。 セッションで送信された各メッセージについて、以下の処理が行なわれる: o クライアントは SN を用いて MAC(req_msg) を計算し、それをリクエストメッ セージに含めてサーバに送信する。リクエスト中に複数のメッセージがある 場合、各々が同じ SN を用いる。(「AndX」機能を用いて) メッセージ中に 複数のリクエストがある場合、MAC の計算は 1 つの大きなリクエストが存 在しているかのようにして行なわれる。 o クライアントは SN の値を増加させ、それを RSN として保存する。 o クライアントは SN の値を増加させる。これが次のリクエストで使われる SN の値となる。 o サーバは各 req_msg を受け取り、 SN を用いて MAC(req_msg) の正当性を 確認し、合致しなかった場合は ACCESS_DENIED をレスポンスとして返却する。 o サーバは SN の値を増加させ、それを RSN として保存する。 o サーバは SN の値を増加させる。これが次のリクエストで使われる SN の値 となる。 o サーバはリクエストに対する各レスポンスのメッセージ毎に、 RSN を用い て MAC(rsp_msg) を計算して、クライアントに対してレスポンスメッセージ として送信する。(「AndX」機能により)メッセージ中に複数のレスポンスが 含まれる場合、MAC の計算は 1 つの大きなレスポンスが存在しているかの ようにして行なわれる。 o クライアントは各 rsp_msg を受け取り、RSN を用いて MAC(rsp_msg) の正 当性を確認し、合致しなかった場合はレスポンスメッセージを破棄する。 2. セキュリティレベルと認証プロトコルのネゴシエーション サーバからの SMB_COM_NEGPROT レスポンスには、SecurityMode フィールドに 以下のようなビットが設定される: #define NEGOTIATE_SECURITY_USER_LEVEL 0x01 #define NEGOTIATE_SECURITY_CHALLENGE_RESPONSE 0x02 Paul Leach Page 5 03/25/97 Preliminary CIFS AuthenticationMay change without notice #define NEGOTIATE_SECURITY_SIGNATURES_ENABLED 0x04 #define NEGOTIATE_SECURITY_SIGNATURES_REQUIRED 0x08 NEGOTIATE_SECURITY_USER_LEVEL が設定されている場合、「ユーザレベル」の セキュリティがサーバ上の全ての共有に対して有効になる。これは、共有への 接続前に、ユーザ認証を行なうため、(SMB_COM_SESSION_SETUP_ANX を用いて)ク ライアントがセッションを確立することが*必須*であり、前述した認証プロト コルで用いられるパスワードは、ユーザのパスワードであることを意味する。 NEGOTIATE_SECURITY_USER_LEVEL が設定されていない場合、「共有レベル」の セキュリティがサーバ上の全ての共有に対して有効になる。これは、セッショ ンの確立が必要ではなく、認証プロトコルで用いられるパスワードは共有に対 するパスワードとなることを意味する。 NEGOTIATE_SECURITY_CHALLENGE_RESPONSE が設定されていない場合、サーバは 平文のパスワードを要求する。(悪意のある者や偽サーバからのダウングレー ドアタックから保護するため)クライアントは平文パスワードの要求を拒否す る設定が可能であることが*必須*であり、これがデフォルトである*べき*であ る。(パスワード推測攻撃に対する堅牢性を高める意味で)サーバも平文パスワー ドを拒否する設定が可能であることが*必須*である。 NEGOTIATE_SECURITY_CHALLENGE_RESPONSE が設定されている場合、サーバは前 述したチャレンジアンドレスポンス認証プロトコルをサポートする。クライア ントもこれをつかう*べき*である。サーバはこれを使わないコネクションを拒 否*してもよい*。また拒否する設定が可能であることが*必須*である。 dialect が「NTLM 0.12」以前の場合、クライアントは「LMセッションキー」 を用いてレスポンスを計算する。dialect が「NTLM 0.12」の場合、クライア ントは「LMセッションキー」と「NTセッションキー」のいずれかもしくは両方 を使ってレスポンスを計算*してもよい*。サーバは「LMセッションキー」を使っ て計算されたレスポンスを拒否*してもよい*。(ダウングレードアタックから 保護するために)そのように設定することが可能であることが*必須*である。 NEGOTIATE_SECURITY_SIGNATURES_ENABLED が設定されている場合、サーバが前 述したメッセージ認証プロトコルをサポートしていれば、クライアントはそれ を利用*してもよい*。このビットは NEGOTIATE_SECURITY_CHALLENGE_RESPONSE が設定されている場合にのみ設定することができる。セキュリティ署名をサポー トするクライアントは NEGOTIATE_SECURITY_SIGNATURES_ENABLED が設定され ていないサーバへの接続を拒否するように設定できることが*必須*であり、そ うしたクライアントは、NEGOTIATE_SECURITY_CHALLENGE_RESPONSE が設定され ているが、NEGOTIATE_SECURITY_USER_LEVEL が設定されていないサーバへの接 続を拒否することが*必須*である (「共有レベル」のセキュリティを使ってい るサーバに対してチャレンジアンドレスポンス認証を行なうことはできない)。 NEGOTIATE_SECURITY_SIGNATURES_REQUIRED が設定されている場合、サーバは 前述したメッセージ認証プロトコルのサポートが要求され、クライアントもそ れを利用することが*必須*である。NEGOTIATE_SECURITY_SIGNATURES_ENABLED が設定されている場合にのみこのビットを設定することができる。 NEGOTIATE_SECURITY_USER_LEVEL が設定されていない場合 (「共有レベル」の セキュリティを使っているサーバの場合)、このビットを設定しないことが*必 須*である。 SMB_COM_SESSION_SETUP_ANDX リクエストには、 Flags2 フィールドの以下の ビットが設定される: Paul Leach Page 6 03/25/97 Preliminary CIFS AuthenticationMay change without notice #define SMB_FLAGS2_SMB_SECURITY_SIGNATURE 0x0004 メッセージ認証を利用する場合、SMB_COM_SESSION_SETUO_ANDX リクエスト中 に、クライアントがサーバに対する SMB_FLAGS2_SMB_SECURITY_SIGNATURE を 設定し、前述した方式で算出された MAC を含める。セッションが NULL でも ゲストでもない場合、SMB_COM_SESSION_SETUP_ANDX のレスポンスおよび後続 の SMB リクエストやレスポンスの全てに、前述した方式で算出された MAC が 含められる。最初の NULL でもゲストでもないセッションによって、後続の全 てのセッションで用いられる MAC に使われるキーが決定される。 メッセージ認証は、dialect として「NTLM 0.12」 がネゴシエーションの結果 選択された場合にのみ要求することができる。メッセージ認証が用いられる場 合、raw mode は利用しないことが*必須*である (これは、raw mode メッセー ジの一部は MAC が運搬されるヘッダを持たないためである) 。 いずれの認証プロトコルがネゴシエーションされた場合でも、サーバはプロト コルを使ったブルートフォースアタックを防止するため、認証の試行の失敗を 繰り返したアカウントを「ロックアウト」する設定を行なえることが*必須*で ある。 2.1 平文パスワードの transport 平文パスワード認証がネゴシエーションされた場合、クライアントは、 SMB_COM_NEGPROT メッセージの交換に続き行なわれる、SMB_COM_TREE_CONNECT, SMB_COM_TREE_CONNECT_ANDX, SMB_COM_SESSION_SETUP_ANDX の内いずれか最初 のリクエストで平文パスワードを送信する。レスポンスを格納する SMB のフィー ルドは、リクエストによって異なり、以下のとおりである: o SMB_COM_TREE_CONNECT の Password o SMB_COM_TREE_CONNECT_ANDX の Password o SMB_COM_SESSION_SETUP_ANDX の AccountPassword、dialect が「NTLM 0.12」より前の場合 o SMB_COM_SESSION_SETUP_ANDX の CaseInsensitivePassword、dialect が 「NTLM 0.12」の場合 o SMB_COM_SESSION_SETUP_ANDX の CaseSensitivePassword、dialect が 「NTLM 0.12」の場合 2.2 チャレンジアンドレスポンス transport サーバからクライアントに送られたチャレンジ C8 は、 SMB_COM_NEGPROT レ スポンス中の EncryptionKey フィールドに含まれている (注意: フィールド 名の「EncryptionKey」は歴史的経緯によるものであり、実際に暗号化キーを 保持しているわけではない)。 クライアントは、SMB_COM_NEGPROT メッセージの交換に続き行なわれる、 SMB_COM_TREE_CONNECT, SMB_COM_TREE_CONNECT_ANDX, SMB_COM_SESSION_SETUP_ANDX の内いずれか最初のリクエストで、平文パスワー Paul Leach Page 7 03/25/97 Preliminary CIFS AuthenticationMay change without notice ドもしくはチャレンジに対するレスポンスを送信する。レスポンスが含まれる SMB フィールドは、リクエストによって異なり、以下のとおりである: o SMB_COM_TREE_CONNECT の Password o SMB_COM_TREE_CONNECT_ANDX の Password o SMB_COM_SESSION_SETUP_ANDX の AccountPassword、dialect が「NTLM 0.12」より前の場合 o SMB_COM_SESSION_SETUP_ANDX の CaseInsensitivePassword、dialect が 「NTLM 0.12」で「LMセッションキー」を使ってレスポンスが計算される 場合 o SMB_COM_SESSION_SETUP_ANDX の CaseInsensitivePassword、dialect が 「NTLM 0.12」の場合 (注意: 繰返しになるが、名称は歴史的経緯によるものであり、実際の使用形 態とは関係がない) 2.3 MAC transport MAC が含まれる各メッセージについて、flags2 フィールドの以下のビットが設 定される: #define SMB_FLAGS2_SMB_SECURITY_SIGNATURES 0x0004 SMB ヘッダは MAC のスペースを確保するために修正されている: typedef struct _SMB_HEADER { UCHAR Protocol[4]; // Contains 0xFF,'SMB' UCHAR Command; // Command code UCHAR ErrorClass; // Error class UCHAR Reserved; // Reserved for future use USHORT Error ; // Error code UCHAR Flags; // Flags USHORT Flags2 ; // More flags union { USHORT Reserved2[6]; // Reserved for future use struct { USHORT PidHigh; // High part of PID // Client must send the correct Signature // for this SMB to be accepted. UCHAR SecuritySignature[8]; }; }; .... } SMB_HEADER; メッセージの送信者は、メッセージ内の SecuritySignature フィールドの最 初の 4 バイトにシーケンス番号 SSN を挿入し、最後の 4 バイトをゼロクリ アしてから、メッセージ全体から MAC を計算して MAC をそこに挿入する。メッ セージの受信者は、SecuritySignature フィールドの値を展開することで、 MAC の正当性を確認する。これは、ESN を SecuritySignature フィールドの Paul Leach Page 8 03/25/97 Preliminary CIFS AuthenticationMay change without notice 先頭 4 バイトに挿入し、後半 4 バイトをゼロクリアした後で、MAC を計算し、 それを展開された値と比較することで行なわれる。 サーバからクライアントに対する oplock の破棄メッセージは、ネゴシエーショ ンが行なわれていた場合であっても、メッセージ認証は使われないことがある。 3. セキュリティ上の考慮点 (これらはすでに CIFS の主要な仕様に含まれており、以下はその一部となる) 関連する補足: メッセージ認証の利用を要求するクライアントは、悪意のある者や偽りのサー バからの man-in-the-middle アタックやダウングレードアタックから保護さ れることになる。メッセージ認証の利用を要求するサーバは、悪意のあるクラ イアントからの man-in-the-middle アタックから保護されることになる。 4. References [FIPS 81] DES, FIPS PUB xxx [RFC 1320] RFC 1320, R. Rivest, The MD4 Message-Digest Algorithm [RFC 1321] RFC 1321, R. Rivest, The MD5 Message-Digest Algorithm [RFC 1828] RFC 1828, P. Metzger, W. Simpson, "IP Authentication using Keyed MD5", August 1995 {Kal 95] B. Kaliski, M.Robshaw, "Message Authentication with MD5", CryptoBytes, Sping 1995, RSA Inc, (http://www.rsa.com/rsalabs/pubs/cryptobytes/spring95/md5.htm) Paul Leach Page 9 03/25/97