C ++ - EncryptMessage不加密正确的数据

时间:2017-02-05 11:44:26

标签: c++ windows ssl

我一直在关注SSL / TLS在线教程(更多的是阅读这些人的源代码并继续阅读)但是我在这个EncryptMessage部分遇到了崎岖不平的道路,因为它推动了数据在路上并加密错误的信息。

我发送的pbloBuffer是:

GET / HTTP/1.1\r\n
HOST: www.google.com\r\n\r\n

但是当我做pbMessage = pbloBuffer + Sizes.cbHeader时;我最终(甚至微软网站说这样做)

1\r\n
HOST: www.google.com\r\n\r\n

现在pbMessage是上面的代码,并且在SECBUFFER_DATA下插入了它,因此它甚至没有获得完整的数据。根据我的理解,SECBUFFER_DATA是"用户" Web服务器将解码和处理的数据。

您能找到解决方法并正确发送加密数据吗?

完整来源:(此代码是实验性的,因为我在进行更改之前试图理解它)

    int Adaptify::EncryptSend(PBYTE pbloBuffer, int Size) {

    SECURITY_STATUS    scRet{ 0 };
    SecBufferDesc      Message{ 0 };
    SecBuffer          Buffers[4]{ 0 };
    DWORD              cbMessage = 0, cbData = 0;
    PBYTE              pbMessage = nullptr;
    SecPkgContext_StreamSizes Sizes = { 0 };
    QueryContextAttributesW(&hContext, SECPKG_ATTR_STREAM_SIZES, &Sizes);

    pbMessage = pbloBuffer + Sizes.cbHeader;
    cbMessage = (DWORD)strlen((const char*)pbMessage);

    Buffers[0].BufferType = SECBUFFER_STREAM_HEADER;
    Buffers[0].cbBuffer = Sizes.cbHeader;
    Buffers[0].pvBuffer = pbloBuffer;

    Buffers[1].BufferType = SECBUFFER_DATA;
    Buffers[1].pvBuffer = pbMessage;
    Buffers[1].cbBuffer = cbMessage;

    Buffers[2].BufferType = SECBUFFER_STREAM_TRAILER;
    Buffers[2].cbBuffer = Sizes.cbTrailer;
    Buffers[2].pvBuffer = pbMessage + cbMessage;

    Buffers[3].BufferType = SECBUFFER_EMPTY;
    Buffers[3].cbBuffer = SECBUFFER_EMPTY;
    Buffers[3].pvBuffer = SECBUFFER_EMPTY;

    Message.cBuffers = 4;
    Message.pBuffers = Buffers;
    Message.ulVersion = SECBUFFER_VERSION;

    scRet = EncryptMessage(&hContext, 0, &Message, 0);
    if (send(hSocket, (const char*)pbloBuffer, Buffers[0].cbBuffer + Buffers[1].cbBuffer + Buffers[2].cbBuffer, 0) < 0) {
        MessageBox(0, L"Send error", 0, 0);
    }


    return 0;
}

1 个答案:

答案 0 :(得分:1)

首先 - 您需要在QueryContextAttributesW返回InitializeSecurityContextW后仅拨打SEC_E_OK一次 - 当您需要发送数据时,无需每次都调用它。并保存结果。如果从SecPkgContext_StreamSizes - class Adaptify : SecPkgContext_StreamSizes;继承您的课程,并在结束握手时调用(一次)QueryContextAttributesW(&hContext, SECPKG_ATTR_STREAM_SIZES, this);

关于发送发送数据 - 在您的情况下Buffers[1].pvBuffer当然必须指向您的实际数据pbloBuffer但不是pbloBuffer + Sizes.cbHeader代码可以是这样的:

int Adaptify::EncryptSend(PBYTE pbloBuffer, int Size) {

    SECURITY_STATUS ss = SEC_E_INSUFFICIENT_MEMORY;

    if (PBYTE Buffer = new BYTE[cbHeader + Size + cbTrailer]) {

        memcpy(Buffer + cbHeader, pbloBuffer, Size);

        SecBuffer sb[4] = {
            { cbHeader, SECBUFFER_STREAM_HEADER, Buffer},
            { Size, SECBUFFER_DATA, Buffer + cbHeader},
            { cbTrailer, SECBUFFER_STREAM_TRAILER, Buffer + cbHeader + Size},
        };

        SecBufferDesc sbd = { 
            SECBUFFER_VERSION, 4, sb
        };

        if (SEC_E_OK == (ss = ::EncryptMessage(this, 0, &sbd, 0)))) {
            if (SOCKET_ERROR == send(hSocket, (const char*)Buffer, sb[0].cbBuffer+sb[1].cbBuffer+sb[2].cbBuffer+sb[3].cbBuffer, 0)) 
                ss = WSAGetLastError();
        }
        delete [] Buffer;
    }
    return ss;
}

因此您需要分配cbHeader + Size + cbTrailer大小的新缓冲区(Size是您的实际消息Size并在Buffer + cbHeader

复制您的消息