ドライバーの公開キーのインポート
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]
ドライバーの RSA 公開キーは、証明書のリーフ ノードの剰余タグと指数タグに含まれています。 どちらの値も base64 でエンコードされ、デコードする必要があります。 Microsoft の CryptoAPI を使用している場合は、暗号化アルゴリズムを実装するモジュールである暗号化サービス プロバイダー (CSP) にキーをインポートする必要があります。
次のコードに示すように、剰余と指数を base64 エンコードからバイナリ配列に変換するには、 CryptStringToBinary 関数を使用します。 関数を 1 回呼び出して、バイト配列のサイズを取得します。 次に、バッファーを割り当てて、関数をもう一度呼び出します。
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 でエンコードされた配列はビッグ エンディアン順ですが、CryptoAPI はリトル エンディアン順で数値を想定しているため、 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 を使用して、ドライバーの公開キーを使用してコマンドと状態要求を暗号化できるようになりました。
関連トピック