В настоящее время я работаю над небольшой программой-примером, использующей Crypto Next Generation (Windows Crypto API) для генерации ключа, сохранения его в модуле TPM на моем компьютере, шифрования некоторых данных, а затем извлечения и дешифрования данных.
Мой выбор RSA-шифрования заключается в том, что это единственный алгоритм, который поддерживает мой TPM.
Я понимаю, что могу получить доступ к TPM как провайдеру, используя:
// Open handle to TPM
if (FAILED(secStatus = NCryptOpenStorageProvider(
&hProv,
MS_PLATFORM_CRYPTO_PROVIDER,
0)))
{
wprintf(L"**** Error 0x%x returned by NCryptOpenStorageProvider\n", secStatus);
goto Cleanup;
}
И это Я могу сгенерировать ключ (какие состояния документации должны сохранить это в моем провайдере):
// Create a persistent key
if (FAILED(secStatus = NCryptCreatePersistedKey(
hProv,
&hKey,
NCRYPT_RSA_ALGORITHM,
L"RSAKey0",
0,
0)))
{
wprintf(L"**** Error 0x%x returned by NCryptCreatePersistedKey\n", secStatus);
goto Cleanup;
}
(а затем установить длину, завершить и т. Д. c)
И, похоже, мои данные зашифровано с помощью команды:
// Encrypt Data
if (!NT_SUCCESS(status = NCryptEncrypt(
hKey, // hKey
InputData, // pbInput
InputDataSize, // cbInput
NULL, // pPaddingInfo
encryptedBuffer, // pbOutput
encryptedBufferSize, // cbOutput
&encryptedBufferSize, // pcbResult
NCRYPT_PAD_PKCS1_FLAG))) // dwFlags
{
wprintf(L"**** Failed to encrypt data. Error 0x%x returned by NCryptEncrypt\n", status);
goto Cleanup;
}
Кажется, что все работает нормально, без ошибок, и данные выглядят зашифрованными. (Боюсь, что, возможно, я неправильно понимаю использование функции здесь с шифрованием RSA и генерацией постоянного ключа в отличие от пары ключей, но, поскольку я не ищу необходимости использовать общий ключ c, я предполагаю, что это должно работать)
Но при попытке извлечь ключ с помощью:
// Get key from TPM
if (FAILED(secStatus = NCryptOpenKey(
hProv,
&hKey,
L"RSAKey0",
0,
0)))
{
wprintf(L"**** Error 0x%x returned by NCryptOpenKey\n", secStatus);
goto Cleanup;
}
я получаю сообщение об ошибке NTE_BAD_KEYSET. Что указывает на то, что ключ не был найден.
Потенциально единственная функция, которую я вижу, что я могу пропустить, - это NCryptExportKey , но если я правильно понимаю, это экспортирует ключ в большой двоичный объект памяти. а не в доверенный платформенный модуль (который должен был быть сохранен при CreatePersistedKey ).
Я пропускаю шаг, чтобы убедиться, что ключ хранится в моем доверенном платформенном модуле?
Кроме того, Я использую NCryptDeleteKey в качестве очистки моей функции шифрования, но в документации говорится, что это просто освобождает дескриптор ключа, а не фактический сохраненный ключ. Как удалить ключ из доверенного платформенного модуля после его хранения там?