I'm trying to create a RSA private key with NCryptCreatePersistedKey
and then later to export it into a BLOB with NCryptExportKey
, but I don't understand why it fails.
This is how I create the private key:
if (NCryptOpenStorageProvider(&providerHandle,
MS_KEY_STORAGE_PROVIDER,
0) != 0)
{
std::cout << "Failed NCryptOpenStorageProvider" << std::endl;
exit(-1);;
}
if (NCryptCreatePersistedKey(providerHandle,
&keyHandle,
NCRYPT_RSA_ALGORITHM,
L"MyKey",
0,
0
) != 0)
{
std::cout << "Failed NCryptCreatePersistedKey" << std::endl;
exit(-1);
}
NTSTATUS status = -1;
DWORD dwBits = 2048;
if (NCryptSetProperty(
keyHandle,
NCRYPT_LENGTH_PROPERTY,
(PBYTE)&dwBits,
sizeof(dwBits),
0
))
{
std::cout << "Failed NCryptSetProperty to key size" << std::endl;
exit(-1);
}
DWORD export_policy = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
if (NCryptSetProperty(
keyHandle,
NCRYPT_EXPORT_POLICY_PROPERTY,
(PBYTE)&export_policy,
sizeof(export_policy),
0))
{
std::cout << "Failed NCryptSetProperty to export policy" << std::endl;
exit(-1);
}
if (NCryptFinalizeKey(keyHandle,
0) != 0)
{
std::cout << "Failed NCryptFinalizeKey" << std::endl;
exit(-1);
}
std::cout << "Private key successfully created." << std::endl;
DWORD blobLength= 0;
if (NCryptExportKey(
keyHandle, // Handle of the key to export
NULL, // Handle of the key used to wrap the exported key
BCRYPT_RSAFULLPRIVATE_BLOB, // Blob type (null terminated unicode string)
NULL, // Parameter list
NULL, // Buffer that recieves the key blob
0, // Buffer length (in bytes)
&blobLength, // Number of bytes copied to the buffer
0) != 0) // Flags
{
std::cout << "Failed to export" << std::endl;
exit(-1);
}
std::cout << "Successfully exported" << std::endl;
The error code thrown by NCryptExportKey
none of those documented in the CNG API (i.e. NTE_BAD_FLAGS, NTE_BAD_KEY_STATE, NTE_BAD_TYPE, NTE_INVALID_HANDLE, NTE_INVALID_PARAMETER)
Maybe the way I create the private key is wrong, something is missing ? Also not sure what blob type I should use in NCryptExportKey.