Статус: Участник
Группы: Участники
Зарегистрирован: 09.08.2013(UTC) Сообщений: 20  Откуда: Grodno Сказал(а) «Спасибо»: 2 раз
|
Татьяна, мы поместили на смарт карту контейнер с закрытым ключом и сертификатом (это с компьютера), открыли этот контейнер на iPad, забрали оттуда сертификат, создали новый контекст сертификата, привязали его к нашему ключевому контейнеру, поместили сертификат в хранилище личных сертификатов. Все вроде бы привязалось хорошо, т.к. нашли этот сертификат в хранилище и прочитали у него к какому контейнеру он привязан - все совпадает, но там где необходим приватный ключ, он не берется из контейнера на смарт карте. Допустим ваш пример sTunnel - мы заранее поместили сертификат с привязкой к контейнеру в хранилище, выбрали его потом из списка, и когда пытаемся открыть тестовую страничку через точку входа в sTunnel у нас появляется та же ошибка, что была когда сертификат в хранилище не был привязан к контейнеру (когда мы тестировали случай с контейнерами в памяти айпад). Ридер читает что то со смарт карты, но ведь по идее у пользователя должен запрашиваться пин код карты для доступа к приватному ключу? добавил тестовый код по добавлению сертификата в хранилище и связи его с контейнером приватного ключа
HCRYPTPROV hCryptProv = 0; //получаем контейнер (для тестового примера он у нас один) if(CryptAcquireContext( &hCryptProv, NULL, CP_KC1_GR3410_2001_PROV, PROV_GOST_2001_DH, CRYPT_VERIFYCONTEXT)) { NSLog(@"A cryptcontext with the key container has been acquired.\n"); DWORD size = 1024; BYTE* ContName = (BYTE*)malloc(1024); DWORD fParam = CRYPT_FIRST; while (CryptGetProvParam(hCryptProv, PP_ENUMCONTAINERS, ContName, &size, fParam) ) { fParam = CRYPT_NEXT; NSLog(@"Container name: %s\n", (char*) ContName ); free(ContName); ContName = (BYTE*)malloc(size); } if (hCryptProv != 0) { CryptReleaseContext(hCryptProv, 0); } //открываем контейнер if(CryptAcquireContext(&hCryptProv, (char*)ContName,CP_KC1_GR3410_2001_PROV, PROV_GOST_2001_DH, 0)) { NSLog(@"Container opened!"); HCRYPTKEY UserKey; if (CryptGetUserKey(hCryptProv, AT_KEYEXCHANGE, &UserKey)) { NSLog(@"Key opened!"); DWORD length; //забираем кодированный сертификат if (CryptGetKeyParam(UserKey, KP_CERTIFICATE, NULL, &length, 0)) { BYTE *container = (BYTE*) malloc(length * sizeof(BYTE)); CryptGetKeyParam(UserKey, KP_CERTIFICATE, container, &length, 0); //выводим сертификат в лог в формате der NSMutableString *hex = [NSMutableString string]; for (int i=0; i < length; i++) { [hex appendFormat:@"%02x ", container[i]]; } NSLog(@"%d", length); NSLog(@"%@", hex);
PCCERT_CONTEXT pCertContext; HCERTSTORE hSystemStore; if((hSystemStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY"))) { NSLog(@"Opened the MY system store."); } //новый контекст для нашего сертификата if((pCertContext = CertCreateCertificateContext(MY_ENCODING_TYPE , container, length))) { NSLog(@"A new certificate has been created"); } else { NSLog(@"A new certificate could not be created"); } CRYPT_KEY_PROV_INFO kpi; ZeroMemory(&kpi, sizeof(kpi)); kpi.pwszContainerName = (wchar_t*)[[NSString stringWithFormat:@"%s", (char*)ContName] cStringUsingEncoding:NSUTF8StringEncoding]; kpi.pwszProvName = (wchar_t*)[[NSString stringWithFormat:@"%s", CP_KC1_GR3410_2001_PROV] cStringUsingEncoding:NSUTF8StringEncoding]; kpi.dwProvType = PROV_GOST_2001_DH; kpi.dwFlags = 0; kpi.dwKeySpec = AT_KEYEXCHANGE; kpi.cProvParam = 0; kpi.rgProvParam = 0;
//прописываем параметры ключевого контейнера для сертификата if (!CertSetCertificateContextProperty(pCertContext ,CERT_KEY_PROV_INFO_PROP_ID, NULL, &kpi)) { CryptDestroyKey(UserKey); CryptReleaseContext(hCryptProv, 0); } NSLog(@"Private key container name setting success!");
//добавляем сертификат в хранилище if(!CertAddCertificateContextToStore(hSystemStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) { NSLog(@"Error adding cert to store!"); } } } else { NSLog(@"%d", CSP_GetLastError()); } } }
Отредактировано пользователем 6 сентября 2013 г. 18:12:24(UTC)
| Причина: Не указана
|