GSSAPI との SSPI/Kerberos 相互運用性
GSSAPI との相互運用性が要件である場合は、 Kerberosセキュリティ サポート プロバイダー (SSP) を使用する場合は注意が必要です。 次のコード規則を使用すると、GSSAPI ベースのアプリケーションとの相互運用性を実現できます。
サンプル コードは、プラットフォーム ソフトウェア開発キット (SDK) の Samples\Security\SSPI\GSS にあります。 さらに、同等の UNIX サンプルは、MIT および Heimdal Kerberos ディストリビューション、GSS クライアント、サーバーに配布されています。
Windows-Compatible名
GSSAPI 関数では、RFC で指定されているgss_nt_service_nameと呼ばれる名前形式が使用されます。 たとえば、 sample@host.dom.com は GSSAPI ベースのアプリケーションで使用できる名前です。 Windows オペレーティング システムはgss_nt_service_name形式を認識せず、完全な サービス プリンシパル名 (サンプル/host.dom.com@REALMなど) を使用する必要があります。
認証
認証は通常、クライアントとサーバーの間の接続が最初に設定されるときに処理されます。 このサンプルでは、クライアントは セキュリティ サポート プロバイダー インターフェイス (SSPI) を使用しており、サーバーは GSSAPI を使用しています。
SSPI クライアントで認証を設定するには
- AcquireCredentialsHandle を使用して送信資格情報を取得します。
- gss_import_name() を使用してサービス名を作成し、gss_acquire_credを使用して受信資格情報を取得します。
- InitializeSecurityContext (Kerberos) を使用してサーバーに送信する認証トークンを取得します。
- トークンをサーバーに送信します。
GSSAPI サーバーで認証を設定するには
クライアントからのメッセージを解析して、セキュリティ トークンを抽出します。 gss_accept_sec_context関数を使用し、トークンを引数として渡します。
サーバーからメッセージを解析して、セキュリティ トークンを抽出します。 このセキュリティ トークンを InitializeSecurityContext (Kerberos) に渡します。
応答トークンをクライアントに送信します。
gss_accept_sec_context関数は、クライアントに返送できるトークンを返すことができます。
続行する必要がある場合は、応答トークンをサーバーに送信します。それ以外の場合は、認証のセットアップが完了します。
続行する必要がある場合は、クライアントからの次のトークンを待ちます。それ以外の場合は、認証のセットアップが完了します。
メッセージの整合性とプライバシー
ほとんどの GSSAPI ベースのアプリケーションでは、 GSS_Wrap 関数を使用してメッセージを送信する前に署名します。 逆に、 GSS_Unwrap 関数はシグネチャを検証します。 GSS_Wrap はバージョン 2.0 の API で使用でき、現在では広く使用されており、プロトコルにセキュリティを追加するための GSSAPI の使用について説明するインターネット標準で指定されています。 以前は、メッセージの整合性とプライバシーのために GSS SignMessage 関数と SealMessage 関数が使用されていました。 GSS_Wrap と GSS_Unwrap は、"conf_flag" 引数の値によって制御されるプライバシーを使用して、整合性とプライバシーの両方に使用されます。
gss_get_micおよびgss_verify_mic関数を使用するように GSSAPI ベースのプロトコルが指定されている場合、正しい SSPI 関数は MakeSignature および VerifySignature になります。 makeSignature と VerifySignature は、conf_flagが 0 に設定されている場合、または GSS_Unwrap でGSS_Wrapと相互運用されないことに注意してください。 同じことが、署名専用に 設定された EncryptMessage (Kerberos) と gss_verify_micを混在する場合にも当てはまります。
注意
GSS_WrapとGSS_Unwrapが呼び出される場合は、MakeSignature 関数または VerifySignature 関数を使用しないでください。
GSS_Wrapと同等の SSPI は、整合性とプライバシーの両方について EncryptMessage (Kerberos) です。
次の例は、 EncryptMessage (Kerberos) を使用して、 GSS_Unwrapによって検証されるデータに署名する方法を示しています。
SSPI クライアントで次の手順を実行します。
// Need three descriptors, two for the SSP and
// one to hold the application data.
in_buf_desc.cBuffers = 3;
in_buf_desc.pBuffers = wrap_bufs;
in_buf_desc.ulVersion = SECBUFFER_VERSION;
wrap_bufs[0].cbBuffer = sizes.cbSecurityTrailer;
wrap_bufs[0].BufferType = SECBUFFER_TOKEN;
wrap_bufs[0].pvBuffer = malloc(sizes.cbSecurityTrailer);
// This buffer holds the application data.
wrap_bufs[1].BufferType = SECBUFFER_DATA;
wrap_bufs[1].cbBuffer = in_buf.cbBuffer;
wrap_bufs[1].pvBuffer = malloc(wrap_bufs[1].cbBuffer);
memcpy(wrap_bufs[1].pvBuffer, in_buf.pvBuffer, in_buf.cbBuffer);
wrap_bufs[2].BufferType = SECBUFFER_PADDING;
wrap_bufs[2].cbBuffer = sizes.cbBlockSize;
wrap_bufs[2].pvBuffer = malloc(wrap_bufs[2].cbBuffer);
maj_stat = EncryptMessage(&context,
SignOnly ? KERB_WRAP_NO_ENCRYPT : 0,
&in_buf_desc, 0);
// Send a message to the server.
GSSAPI サーバーで、次の手順を実行します。
// Received message is in recv_buf.
maj_stat = gss_unwrap(&min_stat, context, &recv_buf, &msg_buf,
&conf_state, (gss_qop_t *) NULL);
(void) gss_release_buffer(&min_stat, &recv_buf);
// Original message is in msg_buf.
GSS_Unwrapと同等の SSPI は DecryptMessage (Kerberos) です。 DecryptMessage (Kerberos) を使用して、GSS_Wrapによって暗号化されたデータを復号化する方法を示す例を次に示します。
GSSAPI サーバーで、次の手順を実行します。
// Seal the message.
send_buf.value = msg;
send_buf.length = msglen;
// If encrypt_flag = 1, privacy; encrypt_flag = 0, integrity.
maj_stat = gss_wrap(&min_stat, context, encrypt_flag,
GSS_C_QOP_DEFAULT, &send_buf, &state, &msg_buf);
// The message to send is in msg_buf.
SSPI クライアントで次の手順を実行します。
wrap_buf_desc.cBuffers = 2;
wrap_buf_desc.pBuffers = wrap_bufs;
wrap_buf_desc.ulVersion = SECBUFFER_VERSION;
// This buffer is for SSPI.
wrap_bufs[0].BufferType = SECBUFFER_STREAM;
wrap_bufs[0].pvBuffer = xmit_buf.pvBuffer;
wrap_bufs[0].cbBuffer = xmit_buf.cbBuffer;
// This buffer holds the application data.
wrap_bufs[1].BufferType = SECBUFFER_DATA;
wrap_bufs[1].cbBuffer = 0;
wrap_bufs[1].pvBuffer = NULL;
maj_stat = DecryptMessage(
&context,
&wrap_buf_desc,
0, // no sequence number
&qop
);
// This is where the data is.
msg_buf = wrap_bufs[1];
// Check QOP of received message.
// If QOP is KERB_WRAP_NO_ENCRYPT, the message is signed only;
// otherwise, it is encrypted.
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示