kitomer
kitomer

Reputation: 33

NCryptOpenKey()

I am trying to create a CNG (Windows Cryptography API Next Generation) key handle by calling NCryptOpenKey() and using the certificate's thumbprint as the key name parameter:

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

Using this keyName the key cannot be found, but I can see the certificate with that thumbprint when I look it up in certmgr.msc ("‎e0 f5 df 72 7f 81 92 fa ae 8a 4b f1 d5 53 c1 be 40 18 90 dc"). What could possibly be the problem here?

Edit: What I essentially want to do (as I found out by the help of the people on stack overflow ;)) is to create a NCRYPT_KEY_HANDLE from a certificate stored in the Windows certificate store.

Upvotes: 0

Views: 4314

Answers (3)

Pavel Ognev
Pavel Ognev

Reputation: 982

If you want to try my example, here is a code:

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 

Upvotes: 0

Pavel Ognev
Pavel Ognev

Reputation: 982

Certificates don't contain the private keys. CERT_CONTEXT can have a CERT_KEY_PROV_INFO_PROP_ID property which say where to find a related private key. It is used by system function CryptAcquireCertificatePrivateKey and other high-level cryptography functions. This property is the only information about private key location in CNG.

Also, you can open every stored key in loop and compare private key BLOB with certificate's one.

Upvotes: 0

Rasmus Faber
Rasmus Faber

Reputation: 49647

The thumbprint and the key name usually has no relationship.

To get the name of the key that is associated with a certificate use CertGetCertificateContextProperty with CERT_KEY_PROV_INFO_PROP_ID.

Upvotes: 1

Related Questions