1

I am attempting to encrypt the buffer which I send trough Winsock. I don't know that much about encryption at all except the absolute basics and I went with Windows' WinCrypt library since it seems the most basic and easiest I can implement, however, I can't seem to get my code to work.

The text is blank following the first attempted encryption (Probably since the Crypt functions fail) and the last error is ERROR_MORE_DATA after the encryption and NTE_BAD_DATA after the decryption attempt.

I have not been able to get much information at all online on either of those errors, they are pretty new to me too.

The MSDN description for ERROR_MORE_DATA says "More data is available" and on the MSDN page for CryptEncrypt (which is the function which throws it) it says that the buffer I give it is not big enough to hold all encrypted data, so I assume, contrary to what I thought, the encryption lengthens the string somehow, but I would need to have a set size given in the structure for my code (at least with my current thought process) so what can I do about that?

Thanks!

I have written the following code for you all to test:

    struct Packet
    {
        char Message[250];
    };

    HCRYPTKEY g_Key;

    bool GenerateKey()
    {
        HCRYPTPROV prov = {};

        if (CryptAcquireContextA(&prov, 0, 0, PROV_RSA_AES, 0))
        {
            if (CryptGenKey(prov, CALG_AES_128, CRYPT_EXPORTABLE, &g_Key))
            {
                return true;
            }
        }
        return false;
    }

    Packet EncryptPacket(Packet Pack)
    {
        DWORD Size;

        Packet NewPacket;
        memcpy(&NewPacket, &Pack, sizeof(Packet));

        if (CryptEncrypt(g_Key, 0, true, 0, reinterpret_cast<BYTE*>(&NewPacket.Message), &Size,
            sizeof(NewPacket.Message)))
        {
            return NewPacket;
        }

        return Packet();
    }

    Packet EncryptPacket(Packet Pack)
    {
        DWORD Size;

        Packet NewPacket;
        memcpy(&NewPacket, &Pack, sizeof(Packet));

        if (CryptDecrypt(g_Key, 0, true, 0, reinterpret_cast<BYTE*>(&NewPacket.Message), &Size))
        {
            return NewPacket;
        }

        return Packet();
    }

int main()
{
    GenerateKey();

    Packet Test;
    strcpy_s(Test.Message, "This is a test!");

    printf("Unencrypted: %s\n", Test.Message);
    printf("Last Error: %x\n", GetLastError());

    Packet EncryptedTest = EncryptPacket(Test);

    printf("Encrypted: %s\n", EncryptedTest.Message);
    printf("Last Error: %x\n", GetLastError());

    Packet DecryptedTest = DecryptPacket(EncryptedTest);

    printf("Decrypted: %s\n", DecryptedTest.Message);
    printf("Last Error: %x\n", GetLastError());

    getchar();

    return 0;
}
dksue
  • 61
  • 3
  • Explain how your compiler does *not* puke on itself with two distinct, yet *identical* declaration+definition of `Packet EncryptPacket(Packet Pack)`. Beyond that, you're not accounting for padding in your target buffer, so the encryption isn't possible for the size you're requesting. Padded encryptions will *always* require more space than your source data (even if your source data lays on a perfect multiple of your key size). Research PKCS15 padding, There are other algorithms, but I believe that is the most prevalent in wincrypt. – WhozCraig Mar 18 '20 at 01:19

0 Answers0