SSPI-/Kerberos-Interoperabilität mit GSSAPI

Bei Verwendung des Kerberos-Sicherheitsunterstützungsanbieters (SSP) muss vorsichtshalber vorgegangen werden, wenn die Interoperabilität mit GSSAPI erforderlich ist. Die folgenden Codekonventionen ermöglichen die Interoperabilität mit GSSAPI-basierten Anwendungen:

Beispielcode finden Sie im Platform Software Development Kit (SDK) unter Samples \ Security \ SSPI \ GSS. Darüber hinaus wird die entsprechende UNIX Beispiel in den MIT- und Heimdal Kerberos-Distributionen, dem GSS-Client und dem Server verteilt.

Windows-Compatible-Namen

GSSAPI-Funktionen verwenden ein Namensformat namens gss _ nt _ service _ name, wie im RFC angegeben. ist beispielsweise ein Name, der sample@host.dom.com in einer GSSAPI-basierten Anwendung verwendet werden kann. Das Windows Betriebssystem erkennt das Format des Dienstnamens gss _ nt _ _ nicht, und der vollständige Dienstprinzipalname, z. B. sample/host.dom.com@REALM , muss verwendet werden.

Authentifizierung

Die Authentifizierung erfolgt in der Regel, wenn eine Verbindung zum ersten Mal zwischen einem Client und einem Server eingerichtet wird. In diesem Beispiel verwendet der Client die Security Support Provider Interface (SSPI) und der Server GSSAPI.

So richten Sie die Authentifizierung im SSPI-Client ein

  1. Abrufen ausgehender Anmeldeinformationen mit acquireCredentialsHandle.
  2. Erstellen Sie einen Dienstnamen mit gss _ import _ name() und erhalten Sie eingehende Anmeldeinformationen mithilfe von gss _ acquire _ cred.
  3. Abrufen eines Authentifizierungstokens, das mithilfe von InitializeSecurityContext (Kerberos)an den Server gesendet werden soll.
  4. Senden Sie das Token an den Server.

So richten Sie die Authentifizierung auf dem GSSAPI-Server ein

  1. Analysieren Sie die Nachricht vom Client, um das Sicherheitstoken zu extrahieren. Verwenden Sie die _ _ _ Kontextfunktion gss accept sec, und übergeben Sie das Token als Argument.

  2. Analysieren Sie die Nachricht vom Server, um das Sicherheitstoken zu extrahieren. Übergeben Sie dieses Sicherheitstoken an InitializeSecurityContext (Kerberos).

  3. Senden Sie ein Antworttoken an den Client.

    Die _ _ _ Kontextfunktion gss accept sec kann ein Token zurückgeben, das Sie an den Client zurücksenden können.

  4. Wenn es erforderlich ist, fortzufahren, senden Sie ein Antworttoken an den Server. Andernfalls ist die Einrichtung der Authentifizierung abgeschlossen.

  5. Wenn es erforderlich ist, fortzufahren, warten Sie auf das nächste Token vom Client. Andernfalls ist die Einrichtung der Authentifizierung abgeschlossen.

Nachrichtenintegrität und Datenschutz

Die meisten GSSAPI-basierten Anwendungen verwenden die GSS _ Wrap-Funktion, um eine Nachricht vor dem Senden zu signieren. Umgekehrt überprüft die _ GSS-Unwrap-Funktion die Signatur. GSS _ Wrap ist in Version 2.0 der API verfügbar und wird jetzt häufig verwendet und in Internetstandards angegeben, die die Verwendung der GSSAPI zum Hinzufügen von Sicherheit zu Protokollen beschreiben. Zuvor wurden die GSS-Funktionen SignMessage und SealMessage für die Nachrichtenintegrität und den Datenschutzverwendet. GSS _ Wrap und GSS _ Unwrap werden sowohl für Integrität als auch für Datenschutz mithilfe des Datenschutzes verwendet, der durch den Wert des Arguments "conf flag" gesteuert _ wird.

Wenn ein GSSAPI-basiertes Protokoll für die Verwendung der gss _ get _ mic- und gss _ verify _ mic-Funktionen angegeben wird, sind makeSignature und VerifySignaturedie richtigen SSPI-Funktionen. Beachten Sie, dass MakeSignature und VerifySignature nicht mit GSS _ Wrap zusammenarbeiten, wenn das _ conf-Flag auf 0 (null) oder mit GSS _ Wrap festgelegt ist. Dasselbe gilt für das Kombinieren des Kerberos-Satzes (EncryptMessage) nur für signature und gss _ verify _ mic.

Hinweis

Verwenden Sie nicht die Funktionen MakeSignature oder VerifySignature, wenn GSS _ Wrap und GSS _ Unwrap aufgerufen werden.

Das SSPI-Äquivalent zu GSS _ Wrap ist EncryptMessage (Kerberos) für Integrität und Datenschutz.

Das folgende Beispiel zeigt die Verwendung von EncryptMessage (Kerberos) zum Signieren von Daten, die von GSS _ Unwrap überprüft werden.

Im SSPI-Client:

// 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.

Auf dem GSSAPI-Server:

// 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.

Das SSPI-Äquivalent zu GSS _ Unwrap ist DecryptMessage (Kerberos). Hier ist ein Beispiel, das zeigt, wie DecryptMessage (Kerberos) zum Entschlüsseln von Daten verwendet wird, die von GSS _ Wrap verschlüsselt wurden.

Auf dem GSSAPI-Server:

// 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.

Im SSPI-Client:

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.