c++11winapicryptoapicngwincrypt

BCryptImportKeyPair returns STATUS_INVALID_PARAMETER when i try to import public key


I followed this example. I am trying to add the public key which i got from the server into the key Pair and I am getting STATUS_INVALID_PARAMETER.

    BCRYPT_DH_KEY_BLOB header;
    header.dwMagic = BCRYPT_DH_PUBLIC_MAGIC;
    header.cbKey = (ULONG)(pub_key.size());
    cout << "header contents " << header.dwMagic << " : " << header.cbKey << endl;
    memcpy(&pubKeyBlobFromServer[0], &header, sizeof(BCRYPT_DH_KEY_BLOB));
    // copy Public key
    cout << "size of pub_key " << pub_key.size() << endl;
    cout << "size of pubKeyBlobFromServer before :" << pubKeyBlobFromServer.size() << endl;
    cout << "size of BCRYPT_DH_KEY_BLOB " << sizeof(BCRYPT_DH_KEY_BLOB) << endl;
    pubKeyBlobFromServer.insert(pubKeyBlobFromServer.end(), pub_key.begin(), pub_key.end());
    cout << "size of pubKeyBlobFromServer after :" << pubKeyBlobFromServer.size() << endl;
    Status = BCryptImportKeyPair(
                                        ExchAlgHandleB,             // Alg handle
                                        nullptr,                       // Parameter not used
                                        BCRYPT_DH_PUBLIC_BLOB,      // Blob type (Null terminated unicode string)
                                        &PubKeyHandleB,             // Key handle that will be recieved
                                        const_cast<PUCHAR>(pubKeyBlobFromServer.data()),            // Buffer than points to the key blob
                                        (ULONG)pubKeyBlobFromServer.size(),     // Buffer length in bytes
                                        0);                         // Flags

I am getting the following output.

header contents 1112557636 : 128
size of pub_key 128
size of pubKeyBlobFromServer before :8
size of BCRYPT_DH_KEY_BLOB 8
size of pubKeyBlobFromServer after :136

I tried printing the bytes of pubKeyBlobFromServer. the public key starts from 8th byte. first 8 is reserved for BCRYPT_DH_KEY_BLOB . I am not sure what is wrong. Please suggest the place where i am making mistake. If not please suggest a sample which imports public key from string. Thanks in Advance.


Solution

  • Microsoft's sample code takes the easy way out; because the same API exported the key, it is already in the right format.

    In order to construct a valid key blob yourself, you need to look up the documentation for the BCRYPT_DH_KEY_BLOB structure:

    A Diffie-Hellman public key BLOB (BCRYPT_DH_PUBLIC_BLOB) has the following format in contiguous memory. The Modulus, Generator, and Public numbers are in big-endian format.

    BCRYPT_DH_KEY_BLOB
    Modulus[cbKey] // Big-endian.
    Generator[cbKey] // Big-endian.
    Public[cbKey] // Big-endian.
    

    Looks like your code was only including one of the three components.