Freigeben über


Signieren einer Nachricht

Wenn ein Client und ein Server die Einrichtung des Sicherheitskontexts abgeschlossen haben, können Nachrichtenunterstützungsfunktionen verwendet werden. Client und Server verwenden das Sicherheitskontexttoken, das beim Erstellen der Sitzung erstellt wurde, um die Funktionen MakeSignature und VerifySignature aufzurufen. Das Kontexttoken kann für den Schutz 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 Aufrufen von MakeSignature ruft der Client QueryContextAttributes (General) mit einer SecPkgContext_Sizes-Struktur auf, um die Länge des Puffers zu bestimmen, der zum Speichern der Nachrichtensignatur erforderlich ist. Wenn das cbMaxSignature-Element 0 ist, unterstützt das Sicherheitspaket keine Signaturnachrichten. Andernfalls gibt dieses Member die Größe des Puffers an, der für den Empfang der Signatur zugeordnet werden soll.

Im Beispiel wird davon ausgegangen, dass eine SecHandle-Variable namens phContext und eine SOCKET-Struktur mit dem Namen s initialisiert werden. Informationen zu Deklarationen und Initiierungen dieser Variablen finden Sie unter Verwenden von SSPI mit einem Windows Sockets-Client und Verwenden von SSPI mit einem Windows Sockets Server. Dieses Beispiel umfasst Aufrufe von Funktionen in Secur32.lib, die in den Linkbibliotheken enthalten sein 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 Signaturnachrichten zugelassen werden und wenn der Eingabepufferdeskriptor ordnungsgemäß formatiert ist. Nachdem die Nachricht signiert wurde, werden die Nachricht und die Signatur mit ihren Längen an den Remotecomputer gesendet.

Hinweis

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