Importation de la clé publique des pilotes

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement au nouveau code d’utiliser MediaPlayer, IMFMediaEngine et La capture audio/vidéo dans Media Foundation au lieu de DirectShow, lorsque cela est possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]

La clé publique RSA du pilote est contenue dans les balises Modulus et Exponent du nœud feuille du certificat. Les deux valeurs sont encodées en base64 et doivent être décodées. Si vous utilisez CryptoAPI de Microsoft, vous devez importer la clé dans un fournisseur de services de chiffrement (CSP), qui est le module qui implémente les algorithmes de chiffrement.

Pour convertir les modulus et les exposants de l’encodage en base64 en tableaux binaires, utilisez la fonction CryptStringToBinary , comme indiqué dans le code suivant. Appelez la fonction une fois pour obtenir la taille du tableau d’octets. Allouez ensuite la mémoire tampon et appelez à nouveau la fonction.

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.)

Le tableau encodé en base64 est dans l’ordre big-endian, tandis que le CryptoAPI attend le nombre dans l’ordre peu endian, vous devez donc permuter l’ordre d’octets du tableau qui est retourné à partir de CryptStringToBinary. Le module est de 256 octets, mais le tableau d’octets décodé peut être inférieur à 256 octets. Si c’est le cas, vous devez allouer un nouveau tableau de 256 octets, copier les données dans le nouveau tableau et ajouter des zéros à l’avant du tableau. L’exposant est une valeur DWORD (4 octets).

Une fois que vous avez les valeurs de module et d’exposant, vous pouvez importer la clé dans le fournisseur de services de chiffrement (CSP) par défaut, comme indiqué dans le code suivant :

// 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) 

Vous pouvez maintenant utiliser cryptoAPI pour chiffrer les commandes et status demandes avec la clé publique du pilote.

Utilisation du protocole COPP (Certified Output Protection Protocol)