Compartir a través de


Firma de un mensaje

Cuando un cliente y un servidor terminen de configurar el contexto de seguridad, se pueden usar funciones de compatibilidad de mensajes. El cliente y el servidor usan el token de contexto de seguridad creado cuando se estableció la sesión para llamar a las funciones MakeSignature y VerifySignature . El token de contexto se puede usar con EncryptMessage (General) y DecryptMessage (General) para la privacidad de las comunicaciones.

En el ejemplo siguiente se muestra el lado cliente que genera un mensaje firmado que se va a enviar al servidor. Antes de llamar a MakeSignature, el cliente llama a QueryContextAttributes (General) con una estructura de SecPkgContext_Sizes para determinar la longitud del búfer necesario para contener la firma del mensaje. Si el miembro cbMaxSignature es cero, el paquete de seguridad no admite la firma de mensajes. De lo contrario, este miembro indica el tamaño del búfer que se va a asignar para recibir la firma.

En el ejemplo se supone que se inicializa una variable SecHandle denominada phContext y una estructura SOCKET denominada s . Para conocer las declaraciones e iniciaciones de estas variables, consulte Uso de SSPI con un cliente de Windows Sockets y Uso de SSPI con un servidor de Windows Sockets. En este ejemplo se incluyen llamadas a funciones de Secur32.lib, que deben incluirse entre las bibliotecas de vínculos.

//--------------------------------------------------------------------
//   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 devuelve TRUE si el contexto está configurado para permitir la firma de mensajes y si el descriptor del búfer de entrada tiene el formato correcto. Una vez firmado el mensaje, el mensaje y la firma con sus longitudes se envían al equipo remoto.

Nota

Se envían los contenidos de datos de las estructuras SecBuffer , no las estructuras SecBuffer ni la estructura SecBufferDesc . Las nuevas estructuras SecBuffer y una nueva estructura SecBufferDesc se crean mediante la aplicación receptora para comprobar la firma.