简体   繁体   中英

Exporting Plaintext AES 128 Key to buffer/file Windows Crypto API c++

I'm having a lot of difficulty understanding and implementing the Windows Crypto API to Import and Export Keys in c++.

Despite reading through the MSDN documentation many many times I can't seem to get it to work in the way I want.

Below is a snippet of code from what i'm working on.

if(CryptAcquireContext(&CryptoHandle,NULL,provPointer, PROV_RSA_AES, 0xF0000000))
{
    HCRYPTKEY aesKey;
    //We now have context on Enhanced AES
    if(CryptGenKey(CryptoHandle,CALG_AES_128,CRYPT_EXPORTABLE,&aesKey))
    {
            DWORD dwBlobLen;
            BYTE* pbKeyBlob;
            CryptExportKey(aesKey,0,PLAINTEXTKEYBLOB,0,NULL,&dwBlobLen);
            if(pbKeyBlob=new BYTE[dwBlobLen])
            {
                if(CryptExportKey(aesKey, NULL,PLAINTEXTKEYBLOB, 0,pbKeyBlob, &dwBlobLen))
                {

                    //Blah Blah
                }

            }
    }

}

*(Where provPointer is a pointer to the Enhanced crypto api string.

As you might be able to tell from the snippet i'm trying to export a AES 128 key to plaintext.

In the debugger it all executes fine (No visible errors) but I don't understand the outcome at all.

The first call to CryptExportKey fills the dwBlobLen with '28' (What does this mean? Why?)

After the second CryptExport key i've tried writing pbKeyBlob(Which I assume points to the key) to file But I just end up with a constant set of bytes (Same for every try) followed by a set of bytes that I different every time (I assume this is some of the key) (Which add to 28 bytes total)

I'd really appreciate if someone could identify where I've gone wrong. I'm pretty clueless with the whole crypto lingo (Sessions,machine keys, blobs etc.)

In the future I'd like to be able to generate an AES key, use it and export it into a file in a form where I can import it again later.

Thanks in advance.

I'm not an expert on the Windows Cryptography API (or on cryptography in general) but I believe I can shed some light on what's going on here.

The first call to CryptExportKey puts 28 in dwBlobLen because that is the size of the blob that it will created when the key is exported. This is in the MSDN docs: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379931%28v=vs.85%29.aspx

AS far as what you're doing wrong. You aren't doing anything wrong. You are asking CryptExportKey to export a plaintext blob which has the following layout:

typedef struct _PLAINTEXTKEYBLOB {
  BLOBHEADER hdr;
  DWORD      dwKeySize;
  BYTE       rgbKeyData[];
} PLAINTEXTKEYBLOB, *PPLAINTEXTKEYBLOB;

As you can see, the blob starts with a header and a key size (which is the constant set of bytes which you have reported, and should be 12 bytes long), followed by the key data (which is the data that changes every time, and should be 16 bytes long). Remember you are generating a 128 bit key (which is 16 bytes).

The BLOBHEADER has the following layout:

typedef struct _BLOBHEADER {
    BYTE bType;
    BYTE bVersion;
    WORD Reserved;
    ALG_ID aiKeyAlg;
} BLOBHEADER;

By the way, from the doc on the CryptImportKey function, you can't import the PLAINTEXTBLOB directly, because the BYTE array that you pass to CryptImportKey does not include the keysize. You need to pass a buffer with the BLOBHEADER followed by the key data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM