| ||||
| ||||
Добрый день, У наших разработчиков ПО возникли сложности с использованием СКЗИ Крипто-Про CSP 2.0. Помогите, пожалуйста. Проблема возникает при следующей последовательности действий: - GetLocalTime() - CryptAcquireContext(), CryptReleaseContext() - SetLocalTime() - перевод времени - CryptAcquireContext(), CryptReleaseContext() - SetLocalTime() - перевод времени - CryptAcquireContext() - возвращает ошибку Инициализация криптопровайдера по имени и типу: CryptAcquireContext(&hProv, 0, prov_name, prov_type, CRYPT_VERIFYCONTEXT) При изменении времени дважды, CryptAcquireContext() возвращает ошибку: NTE_KEYSET_ENTRY_BAD (0x8009001AL) MessageText: Keyset as registered is invalid. The pszContainer key container was found but is corrupt. С другими криптопровайдерами такой ситуации не возникает. Как обойти эту ситуацию? Пример кода: ///////////////////////////////////////////////////////////////////////////////// #include <windows.h> #include <stdio.h> #include <conio.h> void find_prov(); //_________________________________________________ int main() { SYSTEMTIME t; GetLocalTime(&t); find_prov(); t.wHour-=2; SetLocalTime(&t); find_prov(); t.wHour+=2; SetLocalTime(&t); find_prov(); // ошибка при CryptAcquireContext() printf("Press any key ...\n"); while(!kbhit()); return 0; } //_________________________________________________ void find_prov() { printf("find_prov\n"); DWORD dwIndex = 0; for(;;dwIndex++) //перебор провайдеров { DWORD prov_type; char *prov_name = NULL; DWORD prov_name_len = 0; //запросить длину буфера для имени провайдера //получить тип провайдера int rc=CryptEnumProviders(dwIndex, NULL, 0, &prov_type, NULL, &prov_name_len); if(!rc) { printf("end_enum_prov\n"); printf("________________________________________________________________\n"); return; //перебрали всех провайдеров } prov_name = new char[prov_name_len]; //имя прова rc=CryptEnumProviders(dwIndex, NULL, 0, &prov_type, prov_name, &prov_name_len); if(!rc) { delete prov_name; continue; } printf("type:%d\t%s\n",prov_type,prov_name); //по имени и типу HCRYPTPROV hProv; rc=CryptAcquireContext(&hProv, 0, prov_name, prov_type, CRYPT_VERIFYCONTEXT); delete prov_name; if(!rc) { DWORD e = GetLastError(); printf("CryptAcquireContext() CODE:%0x\n",e); char err_message[1000]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) err_message, sizeof(err_message), NULL ); printf("%s\n",err_message); printf("-----------------------\n"); continue; } else CryptReleaseContext(hProv, 0); } //end перебор провайдеров return; } //_________________________________________________ | ||||
Ответы: | ||||
| ||||
Что касается синхронизации часов, то для Solaris/FreeBSD/Linux систем рекомендуется использовать ntp_adjtime()/adjtime()/adjtimex(), а для Windows SetSystemTimeAdjustment(). | ||||