Signieren einer Nachricht

Wenn ein Client und server die Einrichtung des Sicherheitskontexts abgeschlossen haben,können Nachrichtenunterstützungsfunktionen verwendet werden. Client und Server verwenden das Sicherheitskontexttoken, das beim Herstellen der Sitzung zum Aufrufen der Funktionen MakeSignature und VerifySignature erstellt wurde. Das Kontexttoken kann für den Datenschutz bei der Kommunikation mit EncryptMessage (Allgemein) und DecryptMessage (Allgemein) verwendet werden.

Das folgende Beispiel zeigt, wie die Clientseite eine signierte Nachricht generiert, die an den Server gesendet werden soll. Vor dem Aufruf von MakeSignatureruft der Client QueryContextAttributes (Allgemein) mit einer SecPkgContext _ Sizes-Struktur auf, um die Länge des Puffers zu bestimmen, der zum Enthalten der Nachrichtensignatur erforderlich ist. Wenn das cbMaxSignature-Mitglied 0 (null) ist, unterstützt das Sicherheitspaket keine Signierungsmeldungen. Andernfalls gibt dieser Member die Größe des Puffers an, der zum Empfangen der Signatur reserviert werden soll.

Im Beispiel wird davon ausgegangen, dass eine SecHandle-Variable namens phContext und eine SOCKET-Struktur namens s initialisiert werden. Informationen zu den Deklarationen und Initiierungen dieser Variablen finden Sie unter Using SSPI with a Windows Sockets Client (Verwenden von SSPI mit einem Windows Sockets-Client) und Using SSPI with a Windows Sockets Server (Verwenden von SSPI mit einem Windows Sockets-Server). Dieses Beispiel enthält Aufrufe von Funktionen in Secur32.lib, die in die Linkbibliotheken aufgenommen werden müssen.

//--------------------------------------------------------------------
//   Declare and initialize local variables.

SecPkgContext_Sizes ContextSizes;
char *MessageBuffer = "This is a sample buffer to be signed.";
DWORD MessageBufferSize = strlen(MessageBuffer);
SecBufferDesc InputBufferDescriptor;
SecBuffer InputSecurityToken[2];

ss = QueryContextAttributes(
    &phContext,
    SECPKG_ATTR_SIZES,
    &ContextSizes
    );
if(ContextSizes.cbMaxSignature == 0)
{
     MyHandleError("This session does not support message signing.");
}
//--------------------------------------------------------------------
// The message as a byte string is in the variable 
// MessageBuffer, and its length is in MessageBufferSize. 

//--------------------------------------------------------------------
// Build the buffer descriptor and the buffers 
// to pass to the MakeSignature call.

InputBufferDescriptor.cBuffers = 2;
InputBufferDescriptor.pBuffers = InputSecurityToken;
InputBufferDescriptor.ulVersion = SECBUFFER_VERSION;

//--------------------------------------------------------------------
// Build a security buffer for the message itself. If 
// the SECBUFFER_READONLY attribute is set, the buffer will not be
// signed.

InputSecurityToken[0].BufferType = SECBUFFER_DATA;
InputSecurityToken[0].cbBuffer = MessageBufferSize;
InputSecurityToken[0].pvBuffer = MessageBuffer;

//--------------------------------------------------------------------
// Allocate and build a security buffer for the message
// signature.

InputSecurityToken[1].BufferType = SECBUFFER_TOKEN;
InputSecurityToken[1].cbBuffer = ContextSizes.cbMaxSignature;
InputSecurityToken[1].pvBuffer = 
        (void *)malloc(ContextSizes.cbMaxSignature);

//--------------------------------------------------------------------
// Call MakeSignature 
// For the NTLM package, the sequence number need not be specified 
// because the package provides sequencing.
// The quality of service parameter is ignored.

Ss = MakeSignature(
    &phContext,
    0,                       // no quality of service
    &InputBufferDescriptor,  // input message descriptor
    0                        // no sequence number
    );
if (SEC_SUCCESS(ss))
{
     printf("Have made a signature.\n");
}
else
{ 
    MyHandleError("MakeSignature Failed."); 
}

//--------------------------------------------------------------------
//  Send the message.

if(!SendMsg(
    s,
    (BYTE *)InputSecurityToken[0].pvBuffer,
    InputSecurityToken[0].cbBuffer))
{
     MyHandleError("The message was not sent.");
}

//--------------------------------------------------------------------
//   Send the signature.

if(!SendMsg(
     s,
    (BYTE *)InputSecurityToken[1].pvBuffer,
    InputSecurityToken[1].cbBuffer ))
{
     MyHandleError("The signature was not sent.");
}

MakeSignature gibt TRUE zurück, wenn der Kontext so eingerichtet ist, dass signierte Nachrichten zulässig sind und der Eingabepufferdeskriptor ordnungsgemäß formatiert ist. Nachdem die Nachricht signiert wurde, werden die Nachricht und die Signatur mit ihrer Länge an den Remotecomputer gesendet.

Hinweis

Die Dateninhalte der SecBuffer-Strukturen werden gesendet, nicht die SecBuffer-Strukturen selbst oder die SecBufferDesc-Struktur. Neue SecBuffer-Strukturen und eine neue SecBufferDesc-Struktur werden von der empfangenden Anwendung erstellt, um die Signatur zu überprüfen.