Поделиться через


Импорт открытого ключа драйверов

[Функция, связанная с этой страницей, DirectShow, является устаревшей функцией. Он был заменён на MediaPlayer, IMFMediaEngineи Audio/Video Capture в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует, чтобы при написании нового кода использовать MediaPlayer, IMFMediaEngine и аудио- и видеозахват в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает, что существующий код, использующий устаревшие API, будет перезаписан для использования новых API, если это возможно.]

Открытый ключ RSA драйвера содержится в тегах Modulus и Exponent конечного узла сертификата. Оба значения кодируются в кодировке Base64 и должны быть декодированы. Если вы используете CryptoAPI Корпорации Майкрософт, необходимо импортировать ключ в поставщик служб шифрования (CSP), который является модулем, реализующим алгоритмы шифрования.

Чтобы преобразовать модулы и экспоненты из кодировки Base64 в двоичные массивы, используйте функцию CryptStringToBinary, как показано в следующем коде. Вызовите функцию один раз, чтобы получить размер массива байтов. Затем выделите буфер и снова вызовите функцию.

DWORD cbLen = 0, dwSkip = 0, dwFlags = 0;
::CryptStringToBinary(
   pszModulus,  // String that contains the Base64-encoded modulus.
   cchModulus,  // Length of the string, not including the trailing NULL.
   CRYPT_STRING_BASE64,  // Base64 encoding.
   NULL,     // Do not convert yet. Just calculate the length.
   &cbLen,   // Receives the length of the buffer that is required.
   &dwSkip,  // Receives the number of skipped characters.
   &dwFlags  // Receives flags.
);

// Allocate a new buffer.
BYTE *pbBuffer = new BYTE [cbLen];
::CryptStringToBinary(pszModulus, cchModulus, CRYPT_STRING_BASE64, 
    pbBuffer, &cbLen, &dwSkip, &dwFlags);

// (Repeat these steps for the exponent.)

Массив, закодированный в формате Base64, находится в формате big-endian, в то время как CryptoAPI ожидает число в формате little-endian, поэтому необходимо сменить порядок байтов в массиве, возвращаемом из CryptStringToBinary. Модуль равен 256 байтам, но декодированные массивы байтов могут быть меньше 256 байтов. Если это так, необходимо выделить новый массив размером 256 байт, скопировать данные в новый массив и разместить перед массивом нули. Экспонент — это значение DWORD (4-байт).

После того как у вас есть модули и экспонентные значения, вы можете импортировать ключ в поставщик служб шифрования по умолчанию (CSP), как показано в следующем коде:

// Assume the following values exist:
BYTE *pModulus;     // Byte array that contains the modulus.
DWORD cbModulus;    // Size of the modulus in bytes.
DWORD dwExponent;   // Exponent.

// Create a new key container to hold the key. 
::CryptAcquireContext(
    &hCSP,         // Receives a handle to the CSP.
    NULL,          // Use the default key container.
    NULL,          // Use the default CSP.
    PROV_RSA_AES,  // Use the AES provider (public-key algorithm).
    CRYPT_SILENT | CRYPT_NEWKEYSET 
);

// Move the key into the key container. 
// The data format is: PUBLICKEYSTRUC + RSAPUBKEY + key
DWORD cbKeyBlob = cbModulus + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY)
BYTE *pBlob = new BYTE[cbKeyBlob];

// Fill in the data.
PUBLICKEYSTRUC *pPublicKey = (PUBLICKEYSTRUC*)pBlob;
pPublicKey->bType = PUBLICKEYBLOB; 
pPublicKey->bVersion = CUR_BLOB_VERSION;  // Always use this value.
pPublicKey->reserved = 0;                 // Must be zero.
pPublicKey->aiKeyAlg = CALG_RSA_KEYX;     // RSA public-key key exchange. 

// The next block of data is the RSAPUBKEY structure.
RSAPUBKEY *pRsaPubKey = (RSAPUBKEY*)(pBlob + sizeof(PUBLICKEYSTRUC));
pRsaPubKey->magic = RSA1;            // Public key.
pRsaPubKey->bitlen = cbModulus * 8;  // Number of bits in the modulus.
pRsaPubKey->pubexp = dwExponent;     // Exponent.

// Copy the modulus into the blob. Put the modulus directly after the
// RSAPUBKEY structure in the blob.
BYTE *pKey = (BYTE*)(pRsaPubkey + sizeof(RSAPUBKEY));
CopyMemory(pKey, pModulus, cbModulus);

// Now import the key.
HCRYPTKEY hRSAKey;  // Receives a handle to the key.
CryptImportKey(hCSP, pBlob, cbKeyBlob, 0, 0, &hRSAKey) 

Теперь вы можете использовать CryptoAPI для шифрования команд и запросов состояния с открытым ключом драйвера.

использование сертифицированного протокола защиты выходных данных (COPP)