0

NCryptOpenKey()我正在尝试通过调用并使用证书的指纹作为密钥名称参数来创建 CNG(下一代 Windows 加密 API)密钥句柄:

LPCWSTR keyName = L"\0xe0\0xf5\0xdf\0x72\0x7f\0x81\0x92\0xfa\0xae\0x8a\0x4b\0xf1\0xd5\0x53\0xc1\0xbe\0x40\0x18\0x90\0xdc";
NCryptOpenKey( hProvider, &hKey, keyName, 0, 0 );

使用这个 keyName 找不到密钥,但是当我在 certmgr.msc 中查找它时,我可以看到带有该指纹的证书(“‎<code>e0 f5 df 72 7f 81 92 fa ae 8a 4b f1 d5 53 c1 be 40 18 90 直流")。这里可能是什么问题?

编辑:我基本上想要做的(正如我在堆栈溢出人员的帮助下发现的那样;))是从存储在 Windows 证书存储中的证书创建一个 NCRYPT_KEY_HANDLE 。

4

3 回答 3

1

指纹和密钥名称通常没有关系。

要获取与证书关联的密钥的名称,请CertGetCertificateContextProperty使用CERT_KEY_PROV_INFO_PROP_ID.

于 2012-08-23T10:16:17.860 回答
0

如果你想试试我的例子,这里有一个代码:

DATA_BLOB key;
FILE *fil = _wfopen(L"D:\\222.p8", L"rb");
if(fil)
{
    fseek(fil, 0 ,2);
    key.cbData = ftell(fil);
    fseek(fil, 0, 0);
    key.pbData = new BYTE[key.cbData];

    fread(key.pbData, 1, key.cbData, fil);
    fclose(fil);
} else {
    MessageBox(L"Cannot open file", L"Error", MB_ICONERROR);
    return;
}

BCryptBuffer nameBuf;
nameBuf.BufferType = NCRYPTBUFFER_PKCS_KEY_NAME;
nameBuf.pvBuffer = L"killme";
nameBuf.cbBuffer = 14;

NCryptBufferDesc parList;
parList.ulVersion = NCRYPTBUFFER_VERSION;
parList.cBuffers = 1;
parList.pBuffers = &nameBuf;

// No error handlers!!!
NCRYPT_PROV_HANDLE hProv;
NCRYPT_KEY_HANDLE hKey;
NCryptOpenStorageProvider( &hProv, L"Microsoft Software Key Storage Provider", 0 );
NCryptImportKey( hProv, NULL, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, &parList, &hKey, key.pbData, key.cbData, 0 );
NCryptFreeObject( hKey );
NCryptFreeObject( hProv );
return;

And this is my file (in HEX):

30 82 02 78 02 01 00 30 0D 06 09 2A 86 48 86 F7 
0D 01 01 01 05 00 04 82 02 62 30 82 02 5E 02 01 
00 02 81 81 00 BB 13 C9 C6 4A 18 1F 11 1D D3 CB 
E4 6A E2 F4 46 8C 1D 67 7F F2 6E 16 67 C6 81 B9 
D9 93 56 45 0B D5 EA 0F EB 7F F3 1D 83 07 19 3B 
A7 1C 84 82 23 88 44 65 13 79 78 EA E0 B7 AD A8 
4D B6 3C 9B D4 74 48 51 0D E8 60 59 19 D8 28 2B 
49 FE BC 8D BF 62 0D 44 70 70 76 2D 83 5B 2E DE 
9E 97 40 D3 BE 23 36 BB 02 3B F0 17 F2 EA 9A 97 
28 41 39 7F A1 98 6E CB A3 9F 5B B3 81 D8 66 73 
D5 19 63 35 E9 02 03 01 00 01 02 81 80 02 BA 5C 
CF 35 C0 B8 F5 EB 45 18 61 B7 51 4C 95 EE C5 CA 
FE E9 A3 C3 53 36 13 7E DD F6 5B B9 5C 07 D2 DC 
47 E7 30 BE 0B 18 17 BD 1A 9D BC 2C ED A4 62 0D 
9B 45 6D 31 A2 49 EB 65 5B 3A 14 BE 2C F4 DC C8 
9B 94 2C 5A EF 1E 43 00 3E 88 00 D3 F1 0F 6A E3 
14 C1 4D C8 7E 77 BD C8 41 92 8B 7D 2A B5 36 1A 
61 81 9C 38 F1 34 C4 C3 73 57 67 25 4C 93 59 9B 
C7 1B 10 39 F2 B2 2F 85 ED 69 B4 43 01 02 41 00 
EC D9 DD B0 C8 F3 BC 39 77 9F 15 20 D5 80 C7 E3 
F5 36 DB F0 BF AC 27 9E 82 A1 CB 64 F0 26 5A 31 
97 C5 75 B0 CB 42 E3 0D AC F1 69 AF 02 1C 0F F5 
38 7A 75 5C 87 41 16 D7 57 E5 A5 78 BB A4 6E 89 
02 41 00 CA 33 BF CA 34 F6 17 F8 F8 1F 0C FF EE 
62 18 09 22 BD 45 DC 2E E7 5D 6C 0F 66 0E 21 3D 
74 61 35 79 19 56 91 1B 90 93 12 AD BA FA 31 23 
4D D2 AE F8 0F 00 46 DE 6B F4 31 62 E3 88 5F 80 
35 B4 61 02 41 00 C7 78 AC C6 28 57 6D 5C 10 AC 
7F C4 C9 4A CE 0D E4 04 B1 B2 CE 1A 14 BB E0 54 
96 D1 89 97 23 3A C5 11 5D 8E E9 80 89 6C 89 0C 
3F EF 4E 1D 88 2B 03 C7 CE 73 80 CD 86 89 11 D3 
AC 4A 43 ED B5 D1 02 41 00 A7 E7 E3 0A 31 82 6D 
93 B3 CE 6D 08 15 56 E5 A8 A8 6D 4D 96 B2 68 33 
9E A9 06 D1 12 EF 2A 36 12 A6 55 D1 19 BC 2F 08 
C2 08 FB EC 08 63 CD 9A F6 EA 4B E2 A9 F6 C6 E4 
47 22 5B D9 01 9C C0 7B E1 02 41 00 E1 94 F0 BB 
B8 7E E6 CF 38 E0 8D 6B F7 BB E2 47 A2 B6 E4 EB 
A5 C7 15 62 76 C4 BA B8 DC 81 06 24 EB B1 46 9B 
EE 5D AC A5 A6 EB 93 2E B4 E7 F8 A3 CD FB 40 C1 
C9 F9 27 DF 31 8B BB EE 29 4F 63 6D 
于 2012-08-29T14:04:00.477 回答
0

证书不包含私钥。CERT_CONTEXT 可以有一个 CERT_KEY_PROV_INFO_PROP_ID 属性,它说明在哪里可以找到相关的私钥。它被系统函数 CryptAcquireCertificatePrivateKey 和其他高级加密函数使用。该属性是关于 CNG 中私钥位置的唯一信息。

此外,您可以循环打开每个存储的密钥,并将私钥 BLOB 与证书的密钥进行比较。

于 2012-08-27T09:16:52.980 回答