17.05.2006 15:42:54Добавление приват ключа к сертификату Ответов: 5
иван
Делаю, все проходит без ошибок но ключь не ассоциируеться с сертификатом:
HCRYPTKEY hKeyUser = 0;
BYTE *pbKeyBlobUser = NULL;
DWORD dwBlobLenUser;
wchar_t* pszKeyContainerName = L"Test Container Name";
if(CryptAcquireContextW(
&hCertProvUser, pszKeyContainerName,
NULL,
PROV_RSA_FULL,
CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET))
{
printf("A cryptographic provider has been acquired. \n");
}
else
{
//free(pbNameEncoded);

if(CryptAcquireContextW(
&hCertProvUser,
pszKeyContainerName,
NULL,
PROV_RSA_FULL,
CRYPT_MACHINE_KEYSET))
{
printf("A new key container has been created.\n");
}

}
HANDLE hFileUser =::CreateFile("c:\\privkeyuser.txt",
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

if ( hFileUser == INVALID_HANDLE_VALUE)
return;
DWORD dwFileSizeUser =::GetFileSize(hFileUser,NULL);
pbKeyBlobUser = new BYTE[dwFileSizeUser];
DWORD dwBytesUser=0;
ReadFile(hFileUser,pbKeyBlobUser,dwFileSizeUser,&dwBytesUser,NULL);
::CloseHandle(hFileUser);
if(!CryptImportKey(hCertProvUser, pbKeyBlobUser, dwFileSizeUser, 0, 0, &hKeyUser))
{
delete []pbKeyBlobUser;
}
delete []pbKeyBlobUser;
PCCERT_CONTEXT pDesiredCert = NULL;
PCCERT_CONTEXT pCertContext;

if(pCertContext = CertCreateCertificateContext(
MY_ENCODING_TYPE , // The encoding type
pbSignedEncodedCert, // The encoded data from cert
encCertLen)) // The length of the encoded data
{
printf("A new certificate as been created.\n");
}
else
{
printf("A new certificate could not be created.\n");

}
CRYPT_KEY_PROV_INFO kpi;
ZeroMemory(&kpi, sizeof(kpi));
kpi.pwszContainerName = pszKeyContainerName;
kpi.pwszProvName = NULL;
kpi.dwProvType = PROV_RSA_FULL;
kpi.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
kpi.dwKeySpec = AT_KEYEXCHANGE;
kpi.cProvParam = 0;
kpi.rgProvParam = 0;

if (!CertSetCertificateContextProperty(pCertContext,
CERT_KEY_PROV_HANDLE_PROP_ID, 0, &kpi))
{
CryptDestroyKey(hKeyUser);
CryptReleaseContext(hCertProvUser, 0);
}else{
MessageBox(0, "ffff", "fff",MB_OK);
}
HCERTSTORE hSystemStore;
if(hSystemStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY"))
{
printf("Opened the MY system store. \n");
}
if(CertAddCertificateContextToStore(
hSystemStore, // The store handle
pCertContext, // The pointer to a certificate
CERT_STORE_ADD_USE_EXISTING,
NULL))
{
printf("Certificate added to the memory store. \n");
}


CryptDestroyKey(hKeyUser);
 
Ответы:
17.05.2006 15:54:07Kirill Sobolev
Поменяйте местами вызовы CertSetCertificateContextProperty и CertAddCertificateContextToStore
17.05.2006 16:02:16Иван
Попробывал (вот код), ошибок ни каких нет, но и ассоциации с ключом тоже нет... в чем может быть ошибка...?
HCRYPTKEY hKeyUser = 0;
BYTE *pbKeyBlobUser = NULL;
DWORD dwBlobLenUser;
wchar_t* pszKeyContainerName = L"Test Container Name";
if(CryptAcquireContextW(
&hCertProvUser, // Address for handle to be returned.
pszKeyContainerName, // Use the current user's logon name.
NULL, // Use the default provider.
PROV_RSA_FULL, // Need to both encrypt and sign.
CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET)) // No flags needed.
{
printf("A cryptographic provider has been acquired. \n");
}
else
{
//free(pbNameEncoded);

if(CryptAcquireContextW(
&hCertProvUser,
pszKeyContainerName,
NULL,
PROV_RSA_FULL,
CRYPT_MACHINE_KEYSET))
{
printf("A new key container has been created.\n");
}

}
HANDLE hFileUser =::CreateFile("c:\\privkeyuser.txt",
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

if ( hFileUser == INVALID_HANDLE_VALUE)
return;
DWORD dwFileSizeUser =::GetFileSize(hFileUser,NULL);
pbKeyBlobUser = new BYTE[dwFileSizeUser];
DWORD dwBytesUser=0;
ReadFile(hFileUser,pbKeyBlobUser,dwFileSizeUser,&dwBytesUser,NULL);
::CloseHandle(hFileUser);
if(!CryptImportKey(hCertProvUser, pbKeyBlobUser, dwFileSizeUser, 0, 0, &hKeyUser))
{
delete []pbKeyBlobUser;
}
delete []pbKeyBlobUser;
PCCERT_CONTEXT pDesiredCert = NULL;
PCCERT_CONTEXT pCertContext;

if(pCertContext = CertCreateCertificateContext(
MY_ENCODING_TYPE , // The encoding type
pbSignedEncodedCert, // The encoded data from cert
encCertLen)) // The length of the encoded data
{
printf("A new certificate as been created.\n");
}
else
{
printf("A new certificate could not be created.\n");

}
HCERTSTORE hSystemStore;
if(hSystemStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY"))
{
printf("Opened the MY system store. \n");
}
if(CertAddCertificateContextToStore(
hSystemStore, // The store handle
pCertContext, // The pointer to a certificate
CERT_STORE_ADD_USE_EXISTING,
NULL))
{
printf("Certificate added to the memory store. \n");
}

CRYPT_KEY_PROV_INFO kpi;
ZeroMemory(&kpi, sizeof(kpi));
kpi.pwszContainerName = pszKeyContainerName;
kpi.pwszProvName = NULL;
kpi.dwProvType = PROV_RSA_FULL;
kpi.dwFlags = 0;
kpi.dwKeySpec = AT_SIGNATURE;// AT_KEYEXCHANGE;
kpi.cProvParam = 0;
kpi.rgProvParam = 0;

if (!CertSetCertificateContextProperty(pCertContext,
CERT_KEY_PROV_HANDLE_PROP_ID, 0, &kpi))
{
CryptDestroyKey(hKeyUser);
CryptReleaseContext(hCertProvUser, 0);
}

FILE *fp2 = NULL;
fp2 = fopen("certpriv.cer", "wb");
fwrite(pCertContext->pbCertEncoded, pCertContext->cbCertEncoded, sizeof(unsigned char), fp2);
fclose(fp2);
CryptDestroyKey(hKeyUser);
CryptReleaseContext(hCertProvUser, 0);
17.05.2006 16:58:03Kirill Sobolev
CertAddCertificateContextToStore(
hSystemStore, // The store handle
pCertContext, // The pointer to a certificate
CERT_STORE_ADD_USE_EXISTING,
&pDesiredCert);
CertSetCertificateContextProperty(pDesiredCert ,
CERT_KEY_PROV_HANDLE_PROP_ID, 0, &kpi);
17.05.2006 17:37:04Иван
Не получаеться....
код:
PCCERT_CONTEXT pDesiredCert = NULL;
PCCERT_CONTEXT pCertContext;

HCERTSTORE hSystemStore;
if(hSystemStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY"))
{
printf("Opened the MY system store. \n");
}

if(pCertContext = CertCreateCertificateContext(
MY_ENCODING_TYPE , // The encoding type
pbSignedEncodedCert, // The encoded data from cert
encCertLen)) // The length of the encoded data
{
printf("A new certificate as been created.\n");
}
else
{
printf("A new certificate could not be created.\n");

}

CRYPT_KEY_PROV_INFO kpi;
ZeroMemory(&kpi, sizeof(kpi));
kpi.pwszContainerName = pszKeyContainerName;
kpi.pwszProvName = NULL;
kpi.dwProvType = PROV_RSA_FULL;
kpi.dwFlags = 0;
kpi.dwKeySpec = AT_KEYEXCHANGE;// AT_KEYEXCHANGE;
kpi.cProvParam = 0;
kpi.rgProvParam = 0;



CertAddCertificateContextToStore(
hSystemStore, // The store handle
pCertContext, // The pointer to a certificate
CERT_STORE_ADD_USE_EXISTING,
&pDesiredCert);

if (!CertSetCertificateContextProperty(pDesiredCert ,
CERT_KEY_PROV_HANDLE_PROP_ID, 0, &kpi))
{
CryptDestroyKey(hKeyUser);
CryptReleaseContext(hCertProvUser, 0);
}

FILE *fp2 = NULL;
fp2 = fopen("certpriv.cer", "wb");
fwrite(pCertContext->pbCertEncoded, pCertContext->cbCertEncoded, sizeof(unsigned char), fp2);
fclose(fp2);
//CryptDestroyKey(hKeyUser);
//CryptReleaseContext(hCertProvUser, 0);

ссылки на ключь нет, есть предположения,
1) может я не правильно импортирую ключ?
2) может я не верно делаю структуру CRYPT_KEY_PROV_INFO?
3) может я не верно закрываю hKeyUser, hCertProvUser?
поскольку, в запросе на сертификат сохраняется информация о том, где расположен соответствующий секретный ключ. Если ключевой контейнер будет перенесен или переименован до установки сертификата, при установке сертификата системными средствами секретный ключ не будет обнаружен, и связать с ним сертификат не удастся. Если ключевой контейнер будет перенесен или переименован после установки сертификата, то сертификат будет связан с секретным ключом (т.е. в нем по-прежнему будет содержаться информация о наличии и старом местоположении секретного ключа), но при необходимости воспользоваться и сертификатом, и секретным ключом для работы секретный ключ не будет обнаружен. Или, это уже не важно, поскольку я его из файла подгружаю и импортирую?
17.05.2006 19:08:58Иван
Разрешил, проблемму, вобщем спасибо, проблемка кроме выще перечисленных (и исправленных CryptoPro) заключалась, в кешировании ключа. Код (верный):
PCCERT_CONTEXT pDesiredCert = NULL;
PCCERT_CONTEXT pCertContext;

HCERTSTORE hSystemStore;
if(hSystemStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY"))
{
printf("Opened the MY system store. \n");
}

if(pCertContext = CertCreateCertificateContext(
MY_ENCODING_TYPE , // The encoding type
pbSignedEncodedCert, // The encoded data from cert
encCertLen)) // The length of the encoded data
{
printf("A new certificate as been created.\n");
}
else
{
printf("A new certificate could not be created.\n");

}

CRYPT_KEY_PROV_INFO kpi;
ZeroMemory(&kpi, sizeof(kpi));
kpi.pwszContainerName = pszKeyContainerName;
kpi.pwszProvName = NULL;
kpi.dwProvType = PROV_RSA_FULL;
kpi.dwFlags = 0;
kpi.dwKeySpec = AT_KEYEXCHANGE;// AT_KEYEXCHANGE;
kpi.cProvParam = 0;
kpi.rgProvParam = 0;



if(!CertAddCertificateContextToStore(
hSystemStore, // The store handle
pCertContext, // The pointer to a certificate
CERT_STORE_ADD_NEW,
&pDesiredCert))
{
printf("Error!\n");
}

if (!CertSetCertificateContextProperty(pDesiredCert ,
CERT_KEY_PROV_INFO_PROP_ID, 0, &kpi))
{
CryptDestroyKey(hKeyUser);
CryptReleaseContext(hCertProvUser, 0);
}
Всем спасибо, тема закрыта.