| ||||
| ||||
Делаю, все проходит без ошибок но ключь не ассоциируеться с сертификатом: 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); | ||||
Ответы: | ||||
| ||||
Поменяйте местами вызовы CertSetCertificateContextProperty и CertAddCertificateContextToStore | ||||
| ||||
Попробывал (вот код), ошибок ни каких нет, но и ассоциации с ключом тоже нет... в чем может быть ошибка...? 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); | ||||
| ||||
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); | ||||
| ||||
Не получаеться.... код: 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? поскольку, в запросе на сертификат сохраняется информация о том, где расположен соответствующий секретный ключ. Если ключевой контейнер будет перенесен или переименован до установки сертификата, при установке сертификата системными средствами секретный ключ не будет обнаружен, и связать с ним сертификат не удастся. Если ключевой контейнер будет перенесен или переименован после установки сертификата, то сертификат будет связан с секретным ключом (т.е. в нем по-прежнему будет содержаться информация о наличии и старом местоположении секретного ключа), но при необходимости воспользоваться и сертификатом, и секретным ключом для работы секретный ключ не будет обнаружен. Или, это уже не важно, поскольку я его из файла подгружаю и импортирую? | ||||
| ||||
Разрешил, проблемму, вобщем спасибо, проблемка кроме выще перечисленных (и исправленных 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); } Всем спасибо, тема закрыта. | ||||