Compartilhar via


Assinando uma mensagem

Quando um cliente e um servidor terminam de configurar o contexto de segurança, as funções de suporte a mensagens podem ser usadas. O cliente e o servidor usam o token de contexto de segurança criado quando a sessão foi estabelecida para chamar as funções MakeSignature e VerifySignature . O token de contexto pode ser usado com EncryptMessage (Geral) e DecryptMessage (Geral) para privacidade de comunicações.

O exemplo a seguir mostra o lado do cliente gerando uma mensagem assinada para enviar ao servidor. Antes de chamar MakeSignature, o cliente chama QueryContextAttributes (Geral) com uma estrutura SecPkgContext_Sizes para determinar o comprimento do buffer necessário para manter a assinatura da mensagem. Se o membro cbMaxSignature for zero, o pacote de segurança não oferecerá suporte à assinatura de mensagens. Caso contrário, esse membro indica o tamanho do buffer a ser alocado para receber a assinatura.

O exemplo pressupõe que uma variável SecHandle chamada phContext e uma estrutura SOCKET chamada s sejam inicializadas. Para obter as declarações e iniciações dessas variáveis, consulte Usando SSPI com um cliente Windows Sockets e Usando SSPI com um Windows Sockets Server. Este exemplo inclui chamadas para funções em Secur32.lib, que devem ser incluídas entre as bibliotecas de link.

//--------------------------------------------------------------------
//   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 retornará TRUE se o contexto estiver configurado para permitir a assinatura de mensagens e se o descritor do buffer de entrada estiver formatado corretamente. Depois que a mensagem é assinada, a mensagem e a assinatura com seus comprimentos são enviadas para o computador remoto.

Observação

O conteúdo dos dados das estruturas SecBuffer é enviado, não as estruturas SecBuffer em si nem a estrutura SecBufferDesc . Novas estruturas SecBuffer e uma nova estrutura SecBufferDesc são criadas pelo aplicativo receptor para verificar a assinatura.