CNGキー関連の操作

チャプターディレクトリ

  1. はじめに
  2. キーを作成
  3. システム内のキーを表示します
  4. Windowsストアからキーをエクスポートする
  5. キーをWindowsストアにインポート

<b>作成者の能力は限られています。読み取りプロセス中にエラーを見つけた場合は、私に連絡してエラーを指摘し、後で読者が間違った知識を学べないようにしてください。ありがとうございます</ b>

はじめに

CNGは、Cryptography API:Next Generation(CNG)の略です。Windowsプラットフォームでの次世代の暗号化関連APIの総称です。CryptoAPIの代わりに使用できます。CryptoAPIと比較すると、より強力な機能を備えています。

この記事では、CNGを使用してKeyおよび関連するAPIを操作する方法を例の形式で示します。

この記事では例としてRSAキーを使用していますが、DSAおよびECCキーも適用可能です。

キーを作成

現在のバージョンのCNGは、RSA、DSA、およびECCアルゴリズムをサポートしています。ここでは、2048ビットのキー長を持つRSAキーを作成します。2048DSAキーを作成する場合は、システムがそれをサポートしていることを確認してください。私のWin7はサポートされていません。Win10がサポートされています(プロテスト)。

ここでは、次のAPIを順番に使用します:
<code> NCryptOpenStorageProvider </ code>このメソッドは、既存のCNGキーストレージプロバイダーをロードして初期化するために使用されます。2つのKSPが現在のWindowsシステムに組み込まれています:MS_KEY_STORAGE_PROVIDER、MS_SMART_CARD_KEY_STORAGE_PROVIDER。この例では、MS_KEY_STORAGE_PROVI 。
<code> NCryptCreatePersistedKey </ code>このメソッドは、特定のアルゴリズムのキーに使用され、指定されたKSPに格納されます。このメソッドで作成されたキーは、Windowsシステムにファイルとして格納されます。
<code> NCryptSetProperty </ code>このメソッドは、キーのプロパティを設定するために使用されます。この例では、キーの長さを2048ビットに設定するために使用します。
<code> NCryptFinalizeKey </ code>このメソッドは、キーの作成操作が完了したことをWindowsに通知するために使用されます。このメソッドの後、作成したキーは署名の暗号化などの操作に使用できますが、そうでない場合は使用できません
<Code> NCryptFreeObject </ code>このメソッドは、前の操作で使用したシステムハンドルを解放するために使用されます。

int Create2048RSAKey() {
  int errCode = 0;

  NCRYPT_PROV_HANDLE prov = NULL;
  NCRYPT_KEY_HANDLE  key = NULL;
  DWORD keyLength = 2048;
  DWORD policy = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;

  if (errCode = NCryptOpenStorageProvider(&prov, MS_KEY_STORAGE_PROVIDER, 0)) goto done;
  if (errCode = NCryptCreatePersistedKey(prov, &key, NCRYPT_RSA_ALGORITHM, L"TestRSAKey", 0, NCRYPT_OVERWRITE_KEY_FLAG)) goto done;
  if (errCode = NCryptSetProperty(key, NCRYPT_LENGTH_PROPERTY, (PBYTE)(&keyLength), sizeof(keyLength), NCRYPT_PERSIST_FLAG)) goto done;
  if (errCode = NCryptSetProperty(key, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)(&policy), sizeof(policy), NCRYPT_PERSIST_FLAG)) goto done;
  if (errCode = NCryptFinalizeKey(key, 0)) goto done;

done:
  if (prov) NCryptFreeObject(prov);
  if (key) NCryptFreeObject(key);
  return errCode;
}

Windowsコンピューターでこのメソッドを実行すると、作成したキーがシステムに保存されます。
次のセクションでは、CNG APIを使用して、作成したキーの情報を表示します。

システム内のキーを表示します

ここで使用するCNG APIは次のとおりです:
<code> NCryptEnumKeys </ code>このメソッドは、現在のKSPに格納されているすべてのキーをトラバースするために使用されます。
ここでは、そのパラメーターの一部について説明します:
<code> NCryptKeyName ** ppKeyName </ code>このパラメータは、メソッドの戻り値として使用され、現在のキー名、キーアルゴリズム、およびその他の重要な情報を保存します。たとえば、名前は特に重要です。たとえば、この例では、名前を使用してキーのハンドルを取得し、次にキーを使用してその他の操作
<Code> PVOID * ppEnumState </ code>このパラメーターはメソッドの戻り値としても使用されますが、その値は呼び出し元には意味がありません。トラバーサルキーの中間情報を格納します。次回NCryptEnumKeysメソッドの入力パラメーターが呼び出されたとき。このパラメーターがNULLに設定されている場合、トラバーサルは常に現在のKSPの最初のキーの情報を
返します<Code>戻り値</ code>このメソッドがNTE_NO_MORE_ITEMSの値を返すとき、それは現在のKSPのすべてのキーをトラバースしました。
<Code> NCryptOpenKey </ code>このメソッドは、KSPで指定された名前を実行するキーハンドルを取得するために使用されます。
<Code> NCryptGetProperty </ code>このメソッドは、Keyのプロパティを取得するために使用されます。

int ListKeys() {
  int errCode = 0;
  NCRYPT_PROV_HANDLE prov        = NULL;
  NCRYPT_KEY_HANDLE  key         = NULL;
  NCryptKeyName*     pKeyName    = NULL;
  PVOID              pEnumState = NULL;
  
  if (errCode = NCryptOpenStorageProvider(&prov, MS_KEY_STORAGE_PROVIDER, 0)) goto done;
  do {
    errCode = NCryptEnumKeys(prov, 0, &pKeyName, &pEnumState, 0);
    if (errCode == NTE_NO_MORE_ITEMS) break; // all the keys are enumerated
    if (!pKeyName) break; // should not happen
    
    LPCWSTR name = pKeyName->pszName;
    LPCWSTR alg  = pKeyName->pszAlgid;
    
    // get key length property
    DWORD keyLength = 0,  outLen = 0;
    if (errCode = NCryptOpenKey(prov, &key, name, 0, 0)) goto done;
    if (errCode = NCryptGetProperty(key, NCRYPT_LENGTH_PROPERTY, (PBYTE) (&keyLength), sizeof(keyLength), &outLen, 0)) goto done;

    wprintf(L"KeyName: %s, KeyAlgorithm: %s, KeyLength: %d", name, alg, keyLength);
  } while (!errCode);
  
done:
  if (prov) NCryptFreeObject(prov);
  if (key) NCryptFreeObject(key);
  return errCode;
}

コンピューターの最初のセクションで関数を実行してから、ListKeys関数を実行すると、コマンドラインには必ず次の出力が含まれます。

<code> KeyName:TestRSAKey、KeyAlgorithm:RSA、KeyLength:2048 </ code>

Windowsストアからキーをエクスポートする

上記の2つのサブセクションの説明を通じて、Windowsシステムでキーを正常に作成し、キー情報を表示してキーハンドルを取得できます。キーハンドルを使用すると、多くの作業を完了することができます。ただし、多くの場合、キーをどこにでも置く必要があります。ファイルに、あなたの仲間と共有します。

このセクションでは、キーのエクスポートを試みます。

<code> NCryptExportKey </ code>このメソッドは、システム内のキーをメモリblobにエクスポートするために使用されます。
非常に重要なパラメータがあります:
<code> LPCWSTR pszBlobType </ code>は、エクスポートされたメモリblobの形式を制御するために使用されます。この例では、NCRYPT_PKCS8_PRIVATE_KEY_BLOBを使用しています。<B>信じられませんが、このフォーマットは、さらに処理を行うのに最も便利です。BCRYPT_DSA_PUBLIC_BLOB、LEGACY_DSA_PRIVATE_BLOBなど、他のフォーマットは見た目はとてもフレンドリーですが、いつも思っているように見えるとは限りません。そのように機能します。それらの形式は、CryptExportKeyがエクスポートされるときの形式と常に同じであるとは限りません。キーの長さが2048以上になると、現時点でその形式を説明するための対応するドキュメントを見つけることが困難になります。 PKCS8は非常にうまく機能します。</ B>

int ExportKey() {
  int errCode = 0;

  NCRYPT_PROV_HANDLE prov = NULL;
  NCRYPT_KEY_HANDLE  key = NULL;
  BYTE blob[0x1000] = {0};
  DWORD blobLen = 0x1000;

  if (errCode = NCryptOpenStorageProvider(&prov, MS_KEY_STORAGE_PROVIDER, 0)) goto done;
  if (errCode = NCryptOpenKey(prov, &key, L"TestRSAKey", 0, 0)) goto done;
  if (errCode = NCryptExportKey(key, NULL, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, NULL, blob, blobLen, &blobLen, 0)) goto done;

done:
  if (prov) NCryptFreeObject(prov);
  if (key) NCryptFreeObject(key);
  return errCode;
}

関数とキーハンドルを実行するときにエラーコード0x80090029が表示される場合は、キーのNCRYPT_EXPORT_POLICY_PROPERTY属性の値にNCRYPT_ALLOW_EXPORT_FLAGとNCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAGが含まれていることを確認してください(これが、最初のセクションのコードにある理由です)作成されたKeyプロパティをこの値に設定する理由。)

キーにNCRYPT_ALLOW_EXPORT_FLAGとNCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAGが含まれていない場合は、キーをエクスポートできず、キーのハンドルを使用して他の作業のみを実行できます。

キーの属性にNCRYPT_ALLOW_EXPORT_FLAGのみが含まれている場合は、証明書をプレーンテキストとしてエクスポートできないことを意味します。現時点では、NCryptExportKeyの2番目のパラメーターをNULL以外の値に設定する必要があります。対応するコードを持っている、それを私と共有してくれてありがとう!

キーがCryptAPIを介して、または手動でインポートされたPFXである場合、Win10プラットフォームでは、キーにNCRYPT_ALLOW_EXPORT_FLAGマークしかなく、プレーンテキストへのエクスポートをサポートしていない可能性があります。間違っている場合はお知らせください。

キーをWindowsストアにインポート

多くの場合、システムを使用してキーを直接作成するのではなく、既存のキーを使用します。そのため、キーをCNG APIと連携させるには、キーをシステムにインポートする必要があります。作業。ここで示す例では、キーをシステムに保存します。キーをKSPにインポートせずにキーハンドルを取得する場合は、キー名を設定するだけで済みます。

ここでは、PKCS8形式のキーをシステムにインポートします。キーが別の形式の場合は、PKCS8形式に変換する方法と、次の方法を使用して他の使用可能な方法をインポートまたは検索する方法の2つがあります。

ここで言及する価値のある2つの点があります:
<code> NCryptBufferDesc * pParameterList </ code>このパラメーターを使用して、キーのパラメーター情報を設定できます。ここでは、このパラメーターを使用して、システムにインポートするキーの名前を指定します。キーが具体的に設定されている場合名前、キーは一時キーになり、ウィンドウには保存されません。
<Code> DWORD dwFlags </ code>キーをインポートした後でKeyプロパティを設定する必要がある場合は、このパラメータにNCRYPT_DO_NOT_FINALIZE_FLAGを含める必要がありますマーク。この例では、キーをインポートした後、キーのNCRYPT_EXPORT_POLICY_PROPERTYプロパティを設定する必要があるため、NCRYPT_DO_NOT_FINALIZE_FLAGマークを使用しました。NCRYPT_DO_NOT_FINALIZE_FLAGを使用しなかった場合は、NCryptFinalizeKeyメソッドを呼び出さないでください。それ以外の場合は、NCryptFinalizeKeyメソッドを呼び出す必要があります。

int ImportKey() {
  BYTE blob[] = { 0x30,0x82,0x04,0xbd,0x02,0x01,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x82,0x04,0xa7,0x30,0x82,0x04,0xa3,0x02,0x01,
0x00,0x02,0x82,0x01,0x01,0x00,0xad,0xaa,0x8c,0x75,0x51,0x15,0x23,0x55,0xc7,0xec,0x7f,0x0b,0x85,0xf9,0x4b,0x18,0x10,0x60,0xdb,0x3d,0xc2,0xd2,0xcf,0xa6,0x8d,0x09,
0x8a,0xc9,0x7a,0x0e,0x80,0xb8,0x60,0x5a,0x20,0xe7,0xcb,0x52,0x33,0xc0,0xa3,0xc8,0x33,0x05,0xb0,0x45,0x34,0x49,0x59,0x0d,0xff,0xed,0xe5,0xe9,0x42,0xc4,0x05,0x82,
0x1a,0x92,0x67,0x24,0xea,0xc6,0x2a,0x07,0x67,0x07,0x65,0xa9,0xb8,0xe8,0x25,0xa2,0x16,0xe5,0x47,0xf2,0x79,0x98,0xcd,0x7c,0xce,0xbc,0x28,0x95,0x5f,0x9a,0xcd,0x70,
0x30,0xbb,0x7c,0xc9,0xc1,0x55,0xac,0x06,0x42,0xa8,0x86,0x78,0x47,0x69,0xa0,0xfb,0x5e,0x10,0x01,0xe4,0x3a,0xbc,0x09,0xb3,0xfd,0x3f,0x3d,0x3c,0x47,0xe7,0xd2,0x8f,
0xaf,0x2f,0x04,0x38,0x74,0xdc,0x3b,0x74,0x31,0xfb,0x55,0x39,0x94,0xeb,0xe3,0x7c,0x17,0x8d,0x51,0x50,0xa2,0x25,0x87,0x4b,0xfb,0xd2,0x3c,0xb6,0x70,0x45,0xd1,0x55,
0xb0,0x8e,0x9d,0x24,0xcb,0xd7,0xa0,0xc2,0xdd,0xfa,0x7b,0xa4,0x3f,0xd3,0xbe,0x7e,0x09,0x87,0x46,0x37,0xda,0x29,0x7c,0x95,0x85,0x0d,0x6d,0xfc,0xbf,0xbf,0x41,0xbe,
0x79,0x2c,0x83,0x87,0x1b,0x6f,0x24,0x8a,0x60,0x85,0x36,0xf6,0xcb,0x63,0x0c,0x66,0x16,0x0b,0x97,0x4a,0xdc,0xdb,0x91,0x0d,0xf9,0x1d,0x7e,0xae,0xbc,0xd9,0x77,0x39,
0x38,0x3e,0x7b,0x04,0x92,0x71,0x94,0x18,0x66,0xc8,0x77,0x5e,0x5c,0x42,0x16,0xc7,0x18,0x61,0x5a,0xdd,0x4f,0xaf,0x77,0x9a,0x14,0xba,0x39,0x98,0x22,0x73,0x49,0xfa,
0x73,0x2b,0x6d,0x0c,0x3b,0x27,0x02,0x03,0x01,0x00,0x01,0x02,0x82,0x01,0x00,0x2b,0xd2,0xef,0xe2,0xe2,0xf5,0x2c,0x97,0x86,0xfd,0xdd,0x09,0x71,0x63,0x79,0x59,0xb7,
0x38,0x59,0xda,0xfa,0x00,0xec,0xb9,0xa0,0xb9,0x99,0xb6,0x42,0x00,0xca,0xe6,0xbc,0x19,0xc2,0x57,0xfb,0xec,0xe0,0x76,0x6a,0x5e,0x28,0xd1,0xf4,0xab,0x62,0x08,0x68,
0x5a,0xaa,0x0c,0xc4,0x89,0xda,0x79,0x50,0xd2,0x86,0x16,0x0f,0xc5,0x37,0x21,0x8e,0x95,0x93,0xa0,0x40,0x3d,0x56,0x15,0xee,0xf9,0x3a,0x41,0xdd,0xa8,0x08,0x9b,0x50,
0xaf,0x80,0x13,0xe7,0x41,0xda,0x80,0x5b,0xfb,0x45,0xb0,0xea,0x4a,0x97,0x69,0x21,0x21,0xeb,0x4c,0x4f,0xb2,0xa6,0x82,0xb7,0x46,0xf7,0x73,0x9e,0xa6,0x93,0x53,0xc4,
0x37,0x11,0x5f,0x15,0xfa,0xd2,0x42,0x63,0xd6,0x32,0x64,0xf0,0xf1,0xb6,0x3b,0x3a,0xb2,0xc8,0x25,0xc3,0x80,0xa1,0xa3,0xe7,0xb4,0x35,0xab,0x13,0xa9,0x3a,0x40,0xd1,
0x16,0xf6,0x63,0x62,0x62,0xeb,0x7c,0x58,0x4f,0x56,0x94,0xde,0x28,0x8a,0x48,0xc6,0xf0,0x3b,0x88,0x01,0xd3,0x8b,0xc6,0x0b,0x17,0x01,0x10,0x28,0x00,0x9c,0xd0,0x80,
0xc2,0xe8,0x00,0xdc,0x6b,0x37,0x39,0x1c,0xef,0x78,0x34,0x1d,0x49,0x12,0xd4,0x66,0x88,0x20,0x87,0xe2,0x1e,0x2b,0x05,0x26,0x8a,0xa7,0xd0,0x3d,0xe7,0xd0,0x47,0xed,
0xbe,0x1f,0xec,0xd6,0xa1,0xd3,0xe2,0x0e,0xb5,0xe5,0x3c,0xc2,0x83,0x69,0x77,0x36,0x9d,0x80,0x2b,0xe9,0xe1,0x14,0xe0,0xd5,0x27,0x62,0x35,0xc1,0x40,0xc6,0xf2,0x6e,
0xdb,0xc1,0x58,0xb8,0x9c,0xbc,0x83,0x36,0x81,0xfb,0x70,0xae,0x0c,0x5c,0xc1,0x02,0x81,0x81,0x00,0xd2,0x5f,0x19,0x94,0x11,0xb8,0xdc,0x77,0x2e,0x93,0x15,0x50,0x09,
0xa9,0x20,0xf0,0x1b,0xd1,0x3d,0x4a,0x1d,0x2c,0xb6,0x98,0xec,0x11,0xf1,0xe8,0xa0,0x85,0x4c,0xf8,0x14,0x27,0x80,0x26,0xff,0x78,0xa1,0x17,0x52,0xa3,0xbf,0xf6,0xc6,
0x86,0xab,0xca,0x5f,0x1e,0x5e,0x8f,0x78,0x5e,0x71,0x7d,0x2c,0x57,0xbe,0xda,0x80,0xa2,0x8b,0x6a,0x88,0xab,0xcd,0x78,0xc3,0x67,0xf6,0xb5,0x60,0x96,0x5c,0x24,0xac,
0x8c,0x4b,0x77,0x36,0xe2,0x97,0x16,0x87,0x6a,0x03,0xa7,0x36,0x4a,0xdf,0x5d,0xc3,0x6f,0x1f,0x60,0xfd,0x40,0x60,0x0e,0xca,0xb9,0x25,0x37,0xfa,0x50,0xc3,0x82,0x2f,
0x3a,0xeb,0x1b,0xd5,0xe0,0x6f,0x13,0x17,0x7d,0xa4,0xd2,0x97,0xe7,0xd7,0xbb,0x32,0x84,0x1e,0x77,0x02,0x81,0x81,0x00,0xd3,0x55,0x62,0x53,0x35,0x29,0xa5,0x68,0x65,
0x28,0x74,0x16,0x30,0x66,0x3e,0x95,0x8e,0xc6,0xb1,0xdd,0x37,0xae,0x69,0xe7,0xc8,0x62,0x81,0x11,0x57,0x57,0x92,0x2b,0xd8,0x21,0x98,0xf4,0x3f,0xe6,0x6e,0xd1,0x5d,
0xff,0x6f,0x90,0x6b,0x9e,0x68,0x47,0x50,0x6e,0xdf,0x5a,0x12,0x49,0x04,0xe9,0x42,0x7f,0xe1,0x3e,0x05,0x0a,0xa3,0xee,0xca,0xeb,0x40,0x4b,0x89,0x2a,0xa1,0x3c,0x2e,
0xa5,0xad,0xa8,0xc9,0x5e,0xa7,0x70,0x55,0x3f,0x04,0x1d,0x17,0xcb,0xca,0x21,0xf5,0xc3,0x68,0x68,0xb9,0x50,0x98,0xd3,0x3a,0x2c,0x29,0x21,0x3b,0x42,0x12,0x92,0x34,
0xda,0xc5,0xbb,0x0c,0xb2,0xb4,0x86,0x6a,0x4e,0x3f,0x43,0x99,0xc4,0xb7,0x85,0x97,0x36,0x75,0x61,0x28,0xd6,0x84,0xd1,0x02,0x81,0x80,0x36,0x9b,0xa1,0x14,0x22,0x95,
0x8e,0x05,0x11,0xfd,0xf4,0x26,0x56,0x9b,0xa4,0x85,0x2f,0x73,0x5d,0x29,0x83,0xf1,0x3b,0x64,0xee,0xc2,0xa9,0xbc,0xed,0x0e,0x2d,0x30,0xa8,0x6a,0xa8,0x85,0x77,0x03,
0x65,0x2d,0x9c,0xb2,0x0c,0xfe,0x8e,0x02,0x1f,0x4d,0xe4,0xeb,0x09,0x38,0xcc,0xd2,0x17,0x3b,0x9a,0xeb,0x1c,0x0b,0xb4,0x20,0x7d,0x78,0x26,0x0a,0x12,0xc8,0x2a,0x51,
0x2e,0x65,0x5e,0xb1,0x29,0x32,0x0b,0xe8,0x4f,0x1e,0x9f,0x0c,0xaa,0x93,0x9a,0x8b,0x16,0x6f,0xad,0x54,0x3a,0x2f,0x28,0xb0,0x0b,0xc1,0x2d,0x7c,0x2c,0x73,0x2a,0x84,
0x6c,0xf8,0xde,0xed,0x60,0x12,0xc7,0x17,0xd0,0x37,0xe5,0x88,0xe0,0xcc,0x5f,0xe8,0xa9,0x84,0x51,0x12,0x49,0x99,0xba,0x3f,0x39,0x79,0x02,0x81,0x80,0x74,0x65,0x92,
0xc2,0x41,0x85,0xae,0x94,0xd1,0x22,0x76,0xcd,0xc1,0xda,0x8e,0x9d,0xd1,0x05,0x9e,0xf1,0x38,0xb9,0xd7,0x9a,0xd1,0xc3,0x6f,0x53,0x1d,0xc8,0x1d,0xba,0x08,0x50,0x78,
0xee,0x0e,0x43,0xdc,0xc5,0x74,0x00,0x3c,0x72,0x4e,0xd3,0xf0,0x9b,0x56,0xb1,0xba,0x52,0xe1,0xbf,0x55,0xf5,0x23,0xab,0x4b,0x63,0xdd,0x62,0xfe,0xe7,0x86,0xdc,0x0b,
0x8d,0x8e,0xfe,0xeb,0xcf,0x39,0xe2,0x06,0xc3,0xf0,0x25,0x32,0x13,0xac,0xe0,0x08,0x63,0xfd,0xb7,0x40,0x9d,0x73,0xbf,0x2c,0xc2,0x81,0x4e,0xe2,0xdd,0x74,0x2c,0xde,
0x7a,0x6f,0x28,0xf5,0x11,0x92,0x0a,0xec,0xdd,0x19,0x21,0x54,0x4c,0xb4,0x40,0x64,0x97,0xd7,0x19,0x81,0xfb,0x12,0x4d,0xec,0x58,0x97,0x25,0x90,0x01,0x02,0x81,0x81,
0x00,0x9d,0xf3,0x78,0x3e,0x39,0xb6,0x45,0x97,0x2d,0xb2,0xf2,0xdb,0xe3,0xa8,0xe9,0x8e,0x58,0xd7,0x6b,0xfb,0x11,0x25,0x77,0x6b,0xd5,0xd6,0x61,0x39,0xbb,0x04,0x15,
0xc2,0x7d,0xf9,0xc7,0xf1,0x1a,0xce,0xe5,0x40,0x84,0x26,0x83,0x13,0xb4,0x41,0x49,0xa2,0x42,0x71,0x3c,0xed,0x72,0x17,0xa9,0x2a,0x85,0x25,0xea,0x5b,0xf3,0x6e,0xd6,
0x5b,0x49,0xc8,0xda,0xe4,0xaa,0xa4,0xa5,0x96,0x31,0xaa,0x7e,0x10,0xd7,0x8a,0xf8,0x16,0xe0,0xe0,0x21,0x64,0x22,0xfb,0x1c,0x74,0x27,0xbe,0xf7,0x0f,0x0c,0x94,0x4b,
0x47,0xf4,0xfe,0x58,0xe1,0x72,0xb1,0x08,0xac,0x93,0xb5,0x06,0x29,0x78,0xb8,0xb3,0xf8,0xd4,0x2f,0x4e,0x43,0x3a,0x0c,0x14,0x8b,0x00,0xd2,0xd5,0x21,0x93,0x8c,0x5d,
0x85,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 
  };
  DWORD blobLen = 0x4c1;

  int errCode = 0;

  NCRYPT_PROV_HANDLE prov = NULL;
  NCRYPT_KEY_HANDLE  key = NULL;
  DWORD policy = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;

  LPCWSTR name = L"ImportedKey";
  BCryptBuffer cb[1];
  cb[0].BufferType = NCRYPTBUFFER_PKCS_KEY_NAME;
  cb[0].pvBuffer = (void*)name;
  cb[0].cbBuffer = lstrlenW(name) * 2 + 2;
  NCryptBufferDesc desc;
  desc.ulVersion = 0;
  desc.pBuffers = cb;
  desc.cBuffers = 1;
  if (errCode = NCryptOpenStorageProvider(&prov, MS_KEY_STORAGE_PROVIDER, 0)) goto done;
  if (errCode = NCryptImportKey(prov, NULL, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, &desc, &key, blob, blobLen, NCRYPT_DO_NOT_FINALIZE_FLAG)) goto done;
  if (errCode = NCryptSetProperty(key, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)(&policy), sizeof(policy), NCRYPT_PERSIST_FLAG)) goto done;
  if (errCode = NCryptFinalizeKey(key, 0)) goto done;

done:
  if (prov) NCryptFreeObject(prov);
  if (key) NCryptFreeObject(key);
  return errCode;
}

インポートが完了したら、ListKeysを使用して、インポートが成功したかどうかを確認できます。

終わり!

元の記事を27件公開 賞賛された31件 40,000回以上の閲覧

おすすめ

転載: blog.csdn.net/zhaoruixiang1111/article/details/102805653