다음을 통해 공유


메시지 서명

클라이언트와 서버가 보안 컨텍스트 설정을 완료하면 메시지 지원 함수를 사용할 수 있습니다. 클라이언트와 서버는 세션이 설정되었을 때 생성된 보안 컨텍스트 토큰을 사용하여 MakeSignatureVerifySignature 함수를 호출합니다. 컨텍스트 토큰은 통신 개인 정보 보호를 위해 EncryptMessage(일반)DecryptMessage(일반)와 함께 사용할 수 있습니다.

다음 예제에서는 서버로 보낼 서명된 메시지를 생성하는 클라이언트 쪽을 보여줍니다. MakeSignature를 호출하기 전에 클라이언트는 SecPkgContext_Sizes 구조를 사용하여 QueryContextAttributes(일반)를 호출하여 메시지 서명을 보유하는 데 필요한 버퍼의 길이를 결정합니다. cbMaxSignature 멤버가 0이면 보안 패키지는 서명 메시지를 지원하지 않습니다. 그렇지 않으면 이 멤버는 서명을 받기 위해 할당할 버퍼의 크기를 나타냅니다.

이 예제에서는 phContext라는 SecHandle 변수와 s라는 SOCKET 구조체가 초기화되어 있다고 가정합니다. 이러한 변수의 선언 및 시작은 Windows 소켓 클라이언트에서 SSPI 사용 및 Windows 소켓서버에서 SSPI 사용을 참조하세요. 이 예제에는 링크 라이브러리에 포함되어야 하는 Secur32.lib의 함수에 대한 호출이 포함됩니다.

//--------------------------------------------------------------------
//   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 는 컨텍스트가 서명 메시지를 허용하도록 설정되고 입력 버퍼 설명자의 형식이 올바르게 지정된 경우 TRUE 를 반환합니다. 메시지가 서명되면 메시지와 해당 길이의 서명이 원격 컴퓨터로 전송됩니다.

참고

SecBuffer 구조체의 데이터 콘텐츠는 SecBuffer 구조 자체나 SecBufferDesc 구조체가 아니라 전송됩니다.SecBuffer 구조체와 새 SecBufferDesc 구조는 서명을 확인하기 위해 수신 애플리케이션에 의해 만들어집니다.