КриптоПро CSP  

Криптографические объекты СКЗИ "КриптоПро CSP 5.0" и их синхронизация

Построение СКЗИ "КриптоПро CSP 5.0" следует идеологии Microsoft CryptoAPI и использует криптографические объекты трех типов:

Использование CryptoAPI в MSDN World Wide Web link

Объекты идентифицируются дескриптором, работа с объектами определяется интерфейсом СКЗИ "КриптоПро CSP 5.0".

Общая схема работы с объектами

Общая схема организации работы с криптографическими объектами – создание контекста, создание ассоциированных с ним криптографических объектов. Перенос дескрипторов из одного контекста в другой не допускается. Объекты могут уничтожаться самостоятельно. При уничтожении контекста все ассоциированные с ним объекты уничтожаются автоматически.

Возможность переноса объектов между контекстами обеспечивается с помощью данных, получаемых функцией экспорта ключей, а также с помощью значения хэш-функции, получаемого и устанавливаемого в объект хэширования функциями CPGetHashParam() и CPSetHashParam().

Способы организации многопоточной работы

Многопоточная обработка с использованием СКЗИ "КриптоПро CSP 5.0" может быть организована двумя способами:

Первый подход универсален и может использоваться без дополнительных ограничений на синхронизацию объектов.

Второй связан с необходимостью синхронизации объектов криптопровайдера. Если поток вызывает функцию с объектом, блокированным другим потоком, функция возвращает ошибку с кодом ERROR_BUSY (0xaa).

В следующей таблице определены методы блокировки объектов в криптопровайдере "КриптоПро CSP 5.0".

Таблица блокировок криптографических объектов "КриптоПро CSP 5.0"

Имя функцииhProvhKeyhExpKeyhHashПримечание
CPCAcquireContext(), CPAcquireContext()LOCK_WRITE -- -- --
CPCCreateHash(), CPCreateHash() LOCK_READ LOCK_READ -- --
CPCDecrypt(), CPDecrypt() LOCK_READ LOCK_READ LOCK_WRITE -- LOCK_READ LOCK_WRITE (dwFlags&CP_CRYPT_NOKEYWLOCK) ? CRWLOCK_READ : CRWLOCK_WRITE
CPCDeriveKey(), CPDeriveKey() LOCK_READ -- -- LOCK_WRITE
CPCDestroyHash(), CPDestroyHash() LOCK_READ -- -- LOCK_WRITE
CPCDestroyKey(), CPDestroyKey() LOCK_READ LOCK_WRITE -- --
CPCDuplicateHash(), CPDuplicateHash() LOCK_READ -- -- LOCK_READ
CPCDuplicateKey(), CPDuplicateKey() LOCK_READ LOCK_READ -- --
CPCEncrypt(), CPEncrypt() LOCK_READ LOCK_READ LOCK_WRITE -- LOCK_READ LOCK_WRITE (dwFlags&CP_CRYPT_NOKEYWLOCK) ? CRWLOCK_READ : CRWLOCK_WRITE
CPCExportKey(), CPExportKey() LOCK_READ LOCK_READ LOCK_READ LOCK_WRITE -- (dwBlobType == SIMPLEBLOB) && (dwFlags&CP_CRYPT_NOKEYWLOCK) ? CRWLOCK_READ : CRWLOCK_WRITE
CPCGenKey(), CPGenKey() LOCK_READ -- -- --
CPCGenRandom(), CPGenRandom() LOCK_READ -- -- --
CPCGetHashParam(), CPGetHashParam() LOCK_READ -- -- LOCK_WRITE
CPCGetKeyParam(), CPGetKeyParam() LOCK_READ LOCK_WRITE -- --
CPCGetProvParam(), CPGetProvParam() LOCK_READ LOCK_WRITE -- -- -- IsReadOnlyProvParam (dwParam) ? LOCK_READ : LOCK_WRITE
CPCGetUserKey(), CPGetUserKey() LOCK_READ -- -- --
CPCHashData(), CPHashData() LOCK_READ -- -- LOCK_WRITE
CPCHashSessionKey(), CPHashSessionKey()LOCK_READ LOCK_WRITE -- LOCK_WRITE
CPCImportKey(), CPImportKey() LOCK_READ LOCK_WRITE LOCK_READ LOCK_WRITE-- --

hProv: bUKChange ? LOCK_WRITE : LOCK_READ, где bUKChange = IsPRIVATEKEYBLOB(pbData, dwDataLen);

hKey: ((pbData[0] == SIMPLEBLOB) || (pbData[0] == PUBLICKEYBLOB) || ((pbData[0] == DIVERSKEYBLOB) && (CALG_PRO_DIVERS == (*(DWORD*)(pbData + sizeof(BLOBHEADER))))))) ? CRWLOCK_READ : CRWLOCK_WRITE

CPCReleaseContext(), CPReleaseContext()LOCK_WRITE -- -- --
CPCSetHashParam(), CPSetHashParam() LOCK_READ -- -- LOCK_WRITE
CPCSetKeyParam(), CPSetKeyParam() LOCK_READ LOCK_WRITE LOCK_WRITE -- -- bUKChange ? LOCK_WRITE : LOCK_READ, где bUKChange = IsPrivateKeyParam(dwParam, pbData);
CPCSetProvParam(), CPSetProvParam() LOCK_WRITE -- -- --
CPCSignHash(), CPSignHash() LOCK_READ -- -- LOCK_WRITE
CPCVerifySignature(), CPVerifySignature()LOCK_READ LOCK_WRITE LOCK_READ-- LOCK_WRITE (dwFlags&CP_CRYPT_NOKEYWLOCK) ? CRWLOCK_READ : CRWLOCK_WRITE

Объекты ключей и хэширования, как видно из таблицы, в основном блокируются на запись, что связано с динамических характером обработки этих объектов.

Криптографические объекты при многопоточной обработке

Схема блокирования объектов СКЗИ "КриптоПро CSP 5.0" обеспечивает их безопасное использование при конкурентном выполнении операций в различных потоках. Вместе с тем, такое выполнение операций может приводить к неопределённому результату не вследствие ограничений СКЗИ или приложений, а по сути исполняемых операций. Например, результаты вызова функций CPEncrypt() зависят от предыдущих вызовов. Поэтому при многопоточной обработке пользователю следует самостоятельно обеспечивать потоковую безопасность (thread safe) и синхронизацию потоков тем способом, который он сочтёт нужным.