章節(jié)目錄
簡(jiǎn)介創(chuàng)建 Key查看系統(tǒng)中的 Key從 Windows Store 導(dǎo)出 key導(dǎo)入 Key 到 Windows Store
<b>作者能力有限, 如果您在閱讀過(guò)程中發(fā)現(xiàn)任何錯(cuò)誤, 還請(qǐng)您務(wù)必聯(lián)系本人,指出錯(cuò)誤, 避免后來(lái)讀者再學(xué)習(xí)錯(cuò)誤的知識(shí).謝謝!</b>
簡(jiǎn)介
CNG 全稱 Cryptography API: Next Generation (CNG). 是 windows 平臺(tái)下一代加密相關(guān) API 的總稱, 它是 Crypto API 的替代. 比較與 CryptoAPI, 它的功能更加強(qiáng)大.
本文將以實(shí)例的形式給出使用 CNG 操作 Key 的方法以及相關(guān)的 API.
請(qǐng)注意, 文章中我們使用 RSA key 作為示例, DSA 和 ECC key 也是同樣適用的.
創(chuàng)建 Key
CNG 當(dāng)前版本支持了 RSA, DSA, ECC 算法, 這里我們來(lái)創(chuàng)建一個(gè) key 長(zhǎng)度 為 2048 bits 的 RSA key. 注意, 當(dāng)你嘗試創(chuàng)建 2048 的 DSA key 時(shí), 請(qǐng)確保你的系統(tǒng)是否支持, 本人的 Win7 是不支持的, 而 Win10 是支持的(親測(cè)).
這里我們依次使用了以下API:
<code>NCryptOpenStorageProvider</code> 該方法用于加載和初始化一個(gè)已經(jīng)存在 CNG Key Storage Provider. 當(dāng)前 Windows 系統(tǒng)中內(nèi)置了兩個(gè) KSP:MS_KEY_STORAGE_PROVIDER,MS_SMART_CARD_KEY_STORAGE_PROVIDER. 我們例子中使用 MS_KEY_STORAGE_PROVIDER.
<code>NCryptCreatePersistedKey</code> 該方法用于常見一個(gè)特定算法的 Key, 并把它存在指定的 KSP 中. 注意, 這個(gè)方法創(chuàng)建的 key 會(huì)以文件形式存儲(chǔ)在 Windows 系統(tǒng)中.
<code>NCryptSetProperty</code> 該方法用于設(shè)置 key 的屬性. 例子中我們將使用它設(shè)置 key 的長(zhǎng)度為 2048 bits.
<code>NCryptFinalizeKey</code> 該方法用于通知 Windows 我們創(chuàng)建 key 的操作已經(jīng)完成, 調(diào)用該方法后, 我們創(chuàng)建的 Key 將可以被用于簽名加密等操作, 否則不能.
<code>NCryptFreeObject</code> 該方法用于釋放前面操作中我們所使用到系統(tǒng) Handle.
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;
}
當(dāng)你在你的 Windows 電腦上執(zhí)行了該方法之后, 你的系統(tǒng)中就會(huì)存有我們剛剛創(chuàng)建的 Key 了.
下一節(jié), 我們將使用 CNG API 來(lái)查看我們創(chuàng)建的 Key 的信息.
查看系統(tǒng)中的 Key
這里我們將會(huì)使用到的 CNG API 有:
<code>NCryptEnumKeys</code> 該方法用于遍歷保存在當(dāng)前 KSP 中的所有 Key.
這里我們解釋一下它的幾個(gè)參數(shù):
<code>NCryptKeyName **ppKeyName</code> 該參數(shù)作為方法的返回值, 其中保存了當(dāng)前 Key 的名稱, key 算法等重要信息. name 尤為重要, 比如我們例子中會(huì)使用 name 來(lái)獲取該 key 的 handle, 依次來(lái)使用該 key 做更多的操作.
<code>PVOID *ppEnumState</code> 該參數(shù)也作為方法的返回值. 但是它的值對(duì)于調(diào)用者來(lái)說(shuō)是沒有任何意義的. 它存儲(chǔ)了遍歷 key 的中間信息, 是我們下一次調(diào)用 NCryptEnumKeys 方法的入?yún)? 如果將該參數(shù)設(shè)置為 NULL, 遍歷總是會(huì)返回當(dāng)前 KSP 的第一個(gè) Key 的信息.
<code>return value</code> 當(dāng)該方法返回值為 NTE_NO_MORE_ITEMS, 代表已經(jīng)遍歷完了當(dāng)前 KSP 中所有的 Key.
<code>NCryptOpenKey</code> 該方法用于獲取執(zhí)行 KSP 中指定名稱的 Key Handle.
<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 enumeratedif (!pKeyName) break; // should not happenLPCWSTR name = pKeyName->pszName;LPCWSTR alg = pKeyName->pszAlgid;// get key length propertyDWORD 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;
}
如果你在你的電腦上運(yùn)行了第一小節(jié)的函數(shù), 此時(shí)執(zhí)行 ListKeys 函數(shù), 你的命令行中肯定會(huì)包含這樣的輸出:
<code>KeyName: TestRSAKey, KeyAlgorithm: RSA, KeyLength: 2048</code>
從 Windows Store 導(dǎo)出 key
通過(guò)上述兩個(gè)小節(jié)的描述, 我們已經(jīng)成功的在 Windows 系統(tǒng)中創(chuàng)建了 Key, 并且可以查看 Key 的信息, 獲取 Key handle. 使用 Key Handle 我們可以完成很多的工作.但是, 很多時(shí)候我們需要把 Key 到處到文件, 和同伴分享.
這一小節(jié), 我們就來(lái)嘗試把 Key 導(dǎo)出來(lái).
<code>NCryptExportKey</code> 該方法用于將系統(tǒng)中的 Key 導(dǎo)出到 memory blob 中.
它有一個(gè)非常重要的參數(shù):
<code>LPCWSTR pszBlobType</code> 用來(lái)控制導(dǎo)出的 memory blob 的格式. 例子中我們使用 NCRYPT_PKCS8_PRIVATE_KEY_BLOB. <b>相信我,這個(gè)格式將會(huì)是最方便我們做進(jìn)一步處理的格式. 其他的格式, 比如 BCRYPT_DSA_PUBLIC_BLOB, LEGACY_DSA_PRIVATE_BLOB 等格式看起來(lái)很友善, 但是并不總是像你想象的那樣工作. 他們的格式并不總是和 CryptExportKey 導(dǎo)出時(shí)的一致,當(dāng) Key 的長(zhǎng)度變?yōu)?2048 或者更大時(shí), 而且很難找到相應(yīng)的文檔來(lái)描述此時(shí)它的格式到底是什么樣的. 而 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;
}
當(dāng)你執(zhí)行該函數(shù)與某個(gè) Key Handle 時(shí), 如果你得到錯(cuò)誤碼 0x80090029, 請(qǐng)確認(rèn)你的 Key 的 NCRYPT_EXPORT_POLICY_PROPERTY 屬性的值包含 NCRYPT_ALLOW_EXPORT_FLAG 和 NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG.(這就是為什么, 第一節(jié)中的代碼中, 我們明確的將創(chuàng)建的 Key 屬性設(shè)置為該值的原因了.)
如果你的 Key 不包含 NCRYPT_ALLOW_EXPORT_FLAG 和 NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG, 那意味著你的 Key 無(wú)法導(dǎo)出, 你只能使用該 Key 的 Handle 做其他的工作.
如果你的 key 的屬性僅僅包含 NCRYPT_ALLOW_EXPORT_FLAG, 那意味著你不能將你的證書導(dǎo)出為明文. 此時(shí),你需要將 NCryptExportKey 的第二個(gè)參數(shù)設(shè)置為一個(gè)非 NULL 的值. 個(gè)人覺得很麻煩, 如果您有相應(yīng)的 code, 謝謝你分享給我!
一點(diǎn)兒個(gè)人經(jīng)驗(yàn), 如果你的 Key 是用戶通過(guò) CryptAPI 或者手工方式導(dǎo)入的 PFX, 在 Win10 平臺(tái)上, 你的 Key 很可能只有 NCRYPT_ALLOW_EXPORT_FLAG 標(biāo)記, 而不支持導(dǎo)出為明文. 如果我錯(cuò)了, 請(qǐng)告訴我!
導(dǎo)入 Key 到 Windows Store
很多時(shí)候, 我們不總是直接使用系統(tǒng)創(chuàng)建 Key, 而是使用我們現(xiàn)有的 Key. 那么, 當(dāng)你想讓你的 Key 和 CNG API 一起工作的時(shí)候, 導(dǎo)入你的 Key 到系統(tǒng)中將是一個(gè)必須的工作. 注意, 我們這里給出的例子會(huì)將 Key 保存到系統(tǒng)中. 如果你僅僅想要獲取 Key Handle 而不將 Key 導(dǎo)入到 KSP 中, 只需要不設(shè)置 Key name 就行了.
這里我們將會(huì)將 PKCS8 格式的 Key 導(dǎo)入到系統(tǒng)中, 如果你的 Key 是另外的格式, 你有兩個(gè)選擇: 將他轉(zhuǎn)換成 PKCS8 格式然后使用下面方法導(dǎo)入 或者 尋找其他可用的方法.
這里有兩點(diǎn)值得一提:
<code>NCryptBufferDesc *pParameterList</code> 該參數(shù)可以用來(lái)設(shè)置 Key 的參數(shù)信息. 這里我們使用該參數(shù)來(lái)指定將要導(dǎo)入到系統(tǒng)中的 Key 的名稱. 如果專門設(shè)置 Key 名稱, 該 Key 將會(huì)是一個(gè)臨時(shí)的 Key, 就不會(huì)被存儲(chǔ)在 Window 中.
<code>DWORD dwFlags</code> 如果需要在導(dǎo)入 Key 之后設(shè)置 Key 的屬性, 那你需要在這個(gè)參數(shù)中包含 NCRYPT_DO_NOT_FINALIZE_FLAG 標(biāo)記. 例子中我們?cè)趯?dǎo)入 Key 之后, 需要設(shè)置 Key 的 NCRYPT_EXPORT_POLICY_PROPERTY 屬性, 因此我們使用了 NCRYPT_DO_NOT_FINALIZE_FLAG 標(biāo)記. 如果你未使用 NCRYPT_DO_NOT_FINALIZE_FLAG, 就不要額外的調(diào)用 NCryptFinalizeKey 方法, 否則, 請(qǐng)記得調(diào)用 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;
}
導(dǎo)入完成之后, 可以使用 ListKeys 檢查你的導(dǎo)入是否成功了.
END!
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)
總結(jié)
以上是生活随笔為你收集整理的CNG 关于 Key 相关的操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。