メッセージの暗号化
次の例は、セキュリティで保護された接続を介してリモート コンピューターに送信される前に暗号化されているメッセージを示しています。
この例では、 という名前の SecHandle 変数と という名前phContext
s
の SOCKET が初期化されていることを前提としています。 これらの変数の宣言と開始については、「 Windows ソケット クライアントでの SSPI の使用」および「Windows ソケットサーバーでの SSPI の使用」を参照してください。 この例には、Secur32.lib の関数の呼び出しが含まれています。これはリンク ライブラリに含める必要があります。
//--------------------------------------------------------------------
// Declare and initialize local variables.
SecPkgContext_StreamSizes Sizes;
SECURITY_STATUS scRet;
SecBufferDesc Message;
SecBuffer Buffers[4];
SecBuffer *pDataBuffer;
PBYTE pbIoBuffer;
DWORD cbIoBuffer;
DWORD cbIoBufferLength;
PBYTE pbMessage;
DWORD cbMessage;
//--------------------------------------------------------------------
// Get the stream encryption sizes. This needs to
// be done once per connection.
// phContext must have been initialized during the handshake process.
scRet = QueryContextAttributes(
phContext,
SECPKG_ATTR_STREAM_SIZES,
&Sizes);
if(FAILED(scRet))
{
MyHandleError("Error reading SECPKG_ATTR_STREAM_SIZES");
}
//--------------------------------------------------------------------
// Allocate a working buffer. The plaintext sent to EncryptMessage
// can never be more than 'Sizes.cbMaximumMessage', so a buffer
// size of Sizes.cbMaximumMessage plus the header and trailer sizes
// is sufficient for the longest message.
cbIoBufferLength = Sizes.cbHeader +
Sizes.cbMaximumMessage +
Sizes.cbTrailer;
if(!(pbIoBuffer = malloc((BYTE *), cbIoBufferLength)))
{
MyHandleError("Out of memory");
}
//--------------------------------------------------------------------
// Create a plaintext message to be encrypted offset into the data
// buffer by "header size" bytes. This allows encryption in place.
pbMessage = pbIoBuffer + Sizes.cbHeader;
StringCbPrintfA(pbMessage,
cbIoBufferLength - Sizes.cbHeader,
"This is the plaintext message.");
cbMessage = strlen(pbMessage);
//--------------------------------------------------------------------
// Encrypt the plaintext message.
Buffers[0].pvBuffer = pbIoBuffer;
Buffers[0].cbBuffer = Sizes.cbHeader;
Buffers[0].BufferType = SECBUFFER_STREAM_HEADER;
Buffers[1].pvBuffer = pbMessage;
Buffers[1].cbBuffer = cbMessage;
Buffers[1].BufferType = SECBUFFER_DATA;
Buffers[2].pvBuffer = pbMessage + cbMessage;
Buffers[2].cbBuffer = Sizes.cbTrailer;
Buffers[2].BufferType = SECBUFFER_STREAM_TRAILER;
Buffers[3].BufferType = SECBUFFER_EMPTY;
Message.ulVersion = SECBUFFER_VERSION;
Message.cBuffers = 4;
Message.pBuffers = Buffers;
scRet = EncryptMessage(phContext, 0, &Message, 0);
if(FAILED(scRet))
{
MyHandleError("Error returned by EncryptMessage.");
}
//--------------------------------------------------------------------
// Send the encrypted data.
if(!(SendMsg(
s,
pbIoBuffer,
Buffers[0].cbBuffer + Buffers[1].cbBuffer +
Buffers[2].cbBuffer)))
{
MyHandleError("SendMsg failed.");
}