統合 Windows 認証:Negotiate・SSPI・SPNEGO
Windows の統合認証(Integrated Windows Authentication)を理解するには、API、Security Support Provider (SSP)、negotiation mechanism、実際の認証プロトコルを分けて考える必要があります。
| 層 | 用語 | 役割 |
|---|---|---|
| Application protocol | HTTP、SMB、LDAP、RPC など | SSPI が生成した不透明な security token を相手へ運ぶ。 |
| API | Security Support Provider Interface (SSPI) | Application が特定プロトコルの詳細に依存せず、credential と security context を扱うための Windows API。 |
| Security package / SSP | Negotiate、Kerberos、NTLM、Schannel、CredSSP など | SSPI の共通 API の背後で認証や message protection を実装する。 |
| Negotiation mechanism | Simple and Protected GSS-API Negotiation Mechanism (SPNEGO) | 双方が利用できる認証 mechanism を選択する meta-protocol。Windows の Negotiate SSP の基礎になる。 |
| Authentication mechanism | Kerberos、NTLM など | 実際に主体を認証し、session key や security context を確立する。 |
つまり、Negotiate は Kerberos や NTLM と同列の「第三の資格情報検証方式」ではありません。Application が SSPI で Negotiate package を選ぶと、Negotiate SSP が SPNEGO に基づいて双方で利用可能な mechanism を選び、通常は Kerberos または NTLM が実際の認証を行います。
flowchart LR
A[Application<br/>HTTP / SMB / LDAP / RPC] -->|SSPI API| S[SSPI]
S --> N[Negotiate SSP]
N -->|SPNEGO で選択| K[Kerberos SSP]
N -->|SPNEGO で選択| M[NTLM SSP]
K --> T[Opaque security token]
M --> T
T -->|Application protocol が転送| P[Peer]
SSPI と SSP
Section titled “SSPI と SSP”Security Support Provider Interface (SSPI) は Windows authentication の共通 API です。Application や infrastructure service は SSPI を通じて Security Support Provider (SSP) を利用します。SSPI 自体は network transport ではなく、生成した token を HTTP、SMB、RPC などで転送する責任は application protocol 側にあります。
SSPI を利用する主な利点は次のとおりです。
- Application が Kerberos ticket や NTLM message の wire format を直接組み立てずに済む。
- 同じ API で異なる security package を選択できる。
- 認証後の integrity、confidentiality、impersonation などを、確立した security context の能力に応じて利用できる。
- Security token は application から不透明(opaque)として扱われ、session key や ticket cache を application が直接読む必要がない。
SSP と authentication package は Microsoft 文書でも近い文脈で使われますが、ここでは SSPI から選択できる package をまとめて SSP / security package と呼びます。
Negotiate と SPNEGO
Section titled “Negotiate と SPNEGO”SPNEGO は、複数の Generic Security Services (GSS) 互換 mechanism から双方が扱えるものを安全に選ぶための meta-protocol です。単独でユーザーを認証するわけではなく、少なくとも1つの実際の認証 mechanism が必要です。また、SPNEGO token は SMB、HTTP、RPC、LDAP など別の application protocol 内で運ばれ、SPNEGO を単独の transport として利用することはありません。
Windows の Negotiate security package は、通常 Kerberos と NTLM から選択します。Kerberos を使える条件が整っている場合は Kerberos が優先されます。Microsoft の Negotiate 文書では、client application が Kerberos を選択可能にする target name として、次を挙げています。
- Service Principal Name (SPN)
- User Principal Name (UPN)
- NetBIOS account name
特に service への認証では、正しい SPN を target name として渡すことが重要です。SSPI の InitializeSecurityContext 公式文書も、replay attack の軽減のため、有効な SPN を指定するよう求めています。
「Negotiate = 必ず Kerberos」ではない
Section titled “「Negotiate = 必ず Kerberos」ではない”Negotiate を指定しても、最終的に NTLM が選択される場合があります。
- Domain、trust、OS、application の条件により Kerberos を利用できない。
- Client application が Kerberos に必要な target information を提供していない。
- SPN、DNS、KDC 到達性、時刻同期などの Kerberos 前提が成立していない。
- Client と server の security policy や対応 package が一致しない。
ただし、「Kerberos の任意のエラー後に、常に NTLM で再試行される」という意味ではありません。SPNEGO には non-fatal failure に対する Late Fallback がありますが、双方の対応状況と error の種類に依存します。重複 SPN、principal mismatch、policy による NTLM 拒否などは、そのまま認証失敗になることがあります。運用設計では fallback を前提にせず、Kerberos が成立したかを確認します。
HTTP の Negotiate との関係
Section titled “HTTP の Negotiate との関係”HTTP では server が WWW-Authenticate: Negotiate を提示し、client が Authorization: Negotiate <token> で応答する形が典型です。この Negotiate は HTTP authentication scheme の名前で、token 内では SPNEGO を通して Kerberos または NTLM が選択され得ます。
HTTPS と組み合わせた場合も層は別です。
HTTPS: TLS / Schannel が transport を保護HTTP auth: Negotiate / SPNEGO が Kerberos または NTLM を選択Application: IIS などが認証済み identity を認可に利用TLS を使っていることだけでは NTLM fallback は防げず、Negotiate を使っていることだけでも transport 全体が TLS になるわけではありません。
Negotiate Extensions との違い
Section titled “Negotiate Extensions との違い”Negotiate Extensions (NegoExts) は、NTLM / Kerberos 以外の SSP を特定の Microsoft / third-party scenario で選択するための別 authentication package です。Windows の Negotiate package は NegoExts も候補として扱えますが、NegoExts 内で選んだ authentication method が失敗した場合に別 method へ再 negotiation する仕組みではありません。SPNEGO、Negotiate SSP、NegoExts を同じ名称の機能として扱わないことが重要です。
SSPI API の基本フロー
Section titled “SSPI API の基本フロー”SSPI application の概念的な処理は次のとおりです。実際の引数、buffer 管理、error handling は選択 package の API reference を確認してください。
sequenceDiagram
participant CA as Client application
participant CS as Client SSPI
participant SA as Server application
participant SS as Server SSPI
CA->>CS: AcquireCredentialsHandle("Negotiate", OUTBOUND)
SA->>SS: AcquireCredentialsHandle("Negotiate", INBOUND)
loop SEC_I_CONTINUE_NEEDED の間
CA->>CS: InitializeSecurityContext(target SPN, input token)
CS-->>CA: output token
CA->>SA: Application protocol で token を転送
SA->>SS: AcceptSecurityContext(input token)
SS-->>SA: output token
SA->>CA: 必要なら response token を返す
end
CS-->>CA: SEC_E_OK / client security context
SS-->>SA: SEC_E_OK / server security context
主要 API の責務は次のとおりです。
| API | 役割 |
|---|---|
EnumerateSecurityPackages / QuerySecurityPackageInfo | 利用可能な package と capability を調べる。 |
AcquireCredentialsHandle | 既存 logon credential などを参照する credential handle を取得する。これ自体は network logon ではない。 |
InitializeSecurityContext | Client 側の outbound security context を開始・継続し、相手へ送る token を生成する。 |
AcceptSecurityContext | Server 側で受信 token を処理し、inbound security context を開始・継続する。 |
QueryContextAttributes | 選択された package、相手の名前、context capability などを確認する。Negotiate で実際に選ばれた package の確認にも使う。 |
MakeSignature / VerifySignature | 確立した context で message integrity を提供・検証する。 |
EncryptMessage / DecryptMessage | Package が対応する場合に message confidentiality と integrity を提供・検証する。 |
ImpersonateSecurityContext / RevertSecurityContext | Server thread が認証済み client の security context で処理し、元に戻す。 |
DeleteSecurityContext / FreeCredentialsHandle | Context と credential handle を解放する。SSPI が確保した buffer は FreeContextBuffer で解放する。 |
InitializeSecurityContext と AcceptSecurityContext は、SEC_I_CONTINUE_NEEDED などが返る間、複数回呼び出す場合があります。Application は SECBUFFER_TOKEN の内容を解釈せず、そのまま peer へ運びます。最終的な SEC_E_OK だけでなく、返された context attributes が要求した mutual authentication、integrity、confidentiality、delegation を満たすかも確認する必要があります。
セキュリティコンテキストと資格情報の委任
Section titled “セキュリティコンテキストと資格情報の委任”認証成功後に得られる security context は、認証済み identity と session-specific な security state を表します。ただし、次は同義ではありません。
- Security context が確立したこと
- TLS transport が確立したこと
- Server が client の reusable credential を受け取ったこと
- Server が client として別 server へ委任できること
たとえば通常の Kerberos / NTLM による remote authentication では、server が client の平文 password を受け取るわけではありません。別の server へ client identity を委任できるかは、Kerberos delegation、requested context flags、account policy、application の実装などに依存します。CredSSP はこれとは異なり、TLS と SPNEGO の上で user credential 自体を target server へ委任します。
調査と保護の観点
Section titled “調査と保護の観点”- Application が
Negotiate、Kerberos、NTLMのどの package を要求しているかを確認する。 - FQDN と正しい SPN を target name に使い、IP address や曖昧な alias の利用を避ける。
klist、setspn -Q/setspn -X、event log、network trace で、実際に Kerberos ticket が利用されたかを確認する。- NTLM audit / restriction policy を段階的に導入し、fallback に依存する application を特定する。
- HTTP などでは TLS に加え、Extended Protection for Authentication (EPA) と Channel Binding Token (CBT) を検討する。
- Application developer は valid target name を渡し、最終 context attributes を検査し、handle と buffer を確実に解放する。
- 認証 token を log に出力しない。Opaque であっても replay や情報漏えいの調査対象になり得る。
Microsoft の公式資料
Section titled “Microsoft の公式資料”- Security Support Provider Interface Architecture: SSPI architecture、標準 SSP、Negotiate と SPNEGO の関係。
- Microsoft Negotiate: Negotiate SSP の選択動作と Kerberos に必要な target name。
- Using Security Packages: SSPI と Kerberos / NTLM package の利用モデル。
- InitializeSecurityContext (Negotiate): Client 側 context 確立、token loop、target SPN、context attributes。
- AcceptSecurityContext (General): Server 側 context 確立と package 別 API。
- MS-SPNG: SPNEGO Synopsis: SPNEGO、opaque security token、Late Fallback。
- MS-SPNG: Relationship to Other Protocols: SPNEGO を運ぶ SMB、HTTP、RPC、LDAP と、meta-protocol としての位置付け。

