Крипто-Про CSP |
//-------------------------------------------------------------------- // Пример кода, в котором описан процесс проверки подписи, полученной // от пользователя. // В данной программе от пользователя получен пакет, в котором содержится // следующая информация: // - длина BLOBa открытого ключа пользователя // - BLOB открытого ключа пользователя // - длина BLOBa для хранения параметра HP_OID // - BLOB для хранения параметра HP_OID // - длина буфера подписи // - буфер подписи // - длина исходного сообщения // - исходное сообщение // Вся эта информация передается через InputBuffer. // // В действительности процесс расшифрования можно разбить на 2 основные части: // - Инициализация контекста. Для этой части необходимо, чтобы отправителем // сообщения являлся CSP. Для каждого получателя инициализация контектса // осуществляется один раз, после чего может проводится обмен пакетами // с отправителем. // // - Проверка подписи. Для каждого сообщения эта часть процесса // осуществляется заново (после того, как инициализация выполнена, // обмен пакетами может производиться любое число раз). //-------------------------------------------------------------------- NTSTATUS Verify( PCHAR inBuf, ULONG inBufLength, PCHAR outBuf, ULONG *outBufLength ) { //-------------------------------------------------------------------- // Объявление и инициализация переменных. VTABLEPROVSTRUC VTable; HCRYPTPROV hProv; // Дескриптор CSP HCRYPTKEY hKey; // Дескриптор открытого ключа пользователя HCRYPTHASH hHash; // Объект функции хеширования BYTE *keyBLOB = NULL; // BLOB открытого ключа пользователя DWORD keyLen = 0; // Длина BLOBа открытого ключа пользователя BYTE *paramBLOB = NULL; // BLOB для хранения параметра HP_OID DWORD paramLen = 0; // Длина BLOBа для хранения параметра HP_OID BYTE *buffer = NULL; // Буфер подписи DWORD bufLen = 0; // Длина буфера подписи BYTE *message = NULL; // Исходное сообщение DWORD messLen = 0; // Длина исходного сообщения DWORD result; //-------------------------------------------------------------------- // Часть 1 - получение контекста. //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Заполнение таблицы. Необходимо для корректной работы провайдера. VTable.Version = 3; VTable.dwProvType = 75; VTable.pszProvName = "Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider"; VTable.cbContextInfo = 0; VTable.pbContextInfo = NULL; VTable.FuncReturnhWnd = &FunReturnHWnd; VTable.FuncVerifyImage = &FunVerifyImage; //-------------------------------------------------------------------- // Получение дескриптора провайдера без доступа к закрытым ключам. if(CPAcquireContext( &hProv, NULL, CRYPT_VERIFYCONTEXT, &VTable )) { CPSIGNIOCTL_KDPRINT(("CPAcquireContext succeeded.\n")); } else { CPSIGNIOCTL_KDPRINT(("Error: CPAcquireContext Failed.")); return STATUS_UNSUCCESSFUL; } //-------------------------------------------------------------------- // Получение BLOBа открытого ключа пользователя, BLOBа для хранения // параметра HP_OID, буфера подписи, исходного сообщения и их длин // из InputBuffer. memcpy(&keyLen, inBuf, sizeof(DWORD)); keyBLOB = (BYTE*)ExAllocatePoolWithTag( PagedPool, keyLen, CPTEST_POOL ); memcpy(keyBLOB, inBuf + sizeof(DWORD), keyLen); memcpy(¶mLen, inBuf + sizeof(DWORD) + keyLen, sizeof(DWORD)); paramBLOB = (BYTE*)ExAllocatePoolWithTag( PagedPool, paramLen, CPTEST_POOL ); memcpy(paramBLOB, inBuf + 2*sizeof(DWORD) + keyLen, paramLen); memcpy(&bufLen, inBuf + 2*sizeof(DWORD) + keyLen + paramLen, sizeof(DWORD)); buffer = (BYTE*)ExAllocatePoolWithTag( PagedPool, bufLen, CPTEST_POOL ); memcpy(buffer, inBuf + 3*sizeof(DWORD) + keyLen + paramLen, bufLen); memcpy(&messLen, inBuf + 3*sizeof(DWORD) + keyLen + bufLen + paramLen, sizeof(DWORD)); message = (BYTE*)ExAllocatePoolWithTag( PagedPool, messLen, CPTEST_POOL ); memcpy(message, inBuf + 4*sizeof(DWORD) + keyLen + bufLen + paramLen, messLen); //-------------------------------------------------------------------- // Получение откытого ключа пользователя, который создал цифровую подпись // с помощью функции CPImportKey. Она возвращает дескриптор открытого // ключа в hKey. if(CPImportKey( hProv, keyBLOB, keyLen, 0, 0, &hKey)) { CPSIGNIOCTL_KDPRINT(("The key has been imported.\n")); } else { CPSIGNIOCTL_KDPRINT(("Error: CPImportKey Failed.")); return STATUS_UNSUCCESSFUL; } //-------------------------------------------------------------------- // Часть 1 - получение контекста. //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Создание объекта функции хеширования. if(CPCreateHash( hProv, CALG_GR3411, 0, 0, &hHash)) { CPSIGNIOCTL_KDPRINT(("The hash object has been created. \n")); } else { CPSIGNIOCTL_KDPRINT(("Error: CPCreateHash.")); return STATUS_UNSUCCESSFUL; } //-------------------------------------------------------------------- // Установка параметра HP_OID (согласование с CSP). // По умолчанию драйвер работает на наборе параметров 1.2.643.2.2.30.1. // Без установки параметра HP_OID программа будет неверно работать, // если параметры хеширования не будут являться параметрами // по умолчанию. if(CPSetHashParam( hProv, hHash, HP_OID, paramBLOB, 0)) { CPSIGNIOCTL_KDPRINT(("The parameters have been set. \n")); } else { CPSIGNIOCTL_KDPRINT(("Error during SetHashParam.")); return STATUS_UNSUCCESSFUL; } //-------------------------------------------------------------------- // Вычисление криптографического хеша сообщения. if(CPHashData( hProv, hHash, message, messLen, 0)) { CPSIGNIOCTL_KDPRINT(("The hash has been created.\n")); } else { CPSIGNIOCTL_KDPRINT(("Error: CPHashData.")); return STATUS_UNSUCCESSFUL; } //-------------------------------------------------------------------- // Проверка цифровой подписи и передача в OutputBuffer результата. if(CPVerifySignature( hProv, hHash, buffer, bufLen, hKey, NULL, 0)) { CPSIGNIOCTL_KDPRINT(("The signature has been verified.\n")); result = TRUE; memcpy(outBuf, &result, sizeof(DWORD)); } else { CPSIGNIOCTL_KDPRINT(("Signature not validated!\n")); result = FALSE; memcpy(outBuf, &result, sizeof(DWORD)); } *outBufLength = sizeof(DWORD); // Освобождение памяти. ExFreePool( keyBLOB ); ExFreePool( paramBLOB ); ExFreePool( buffer ); ExFreePool( message ); // Уничтожение дескриптора открытого ключа. if(hKey) CPDestroyKey(hProv, hKey); //-------------------------------------------------------------------- // Уничтожение объекта функции хеширования. if(hHash) CPDestroyHash(hProv, hHash); // Освобождение дескриптора провайдера. if(hProv) CPReleaseContext(hProv, 0); return STATUS_SUCCESS; }// Конец Verify
Ядро Windows 2000/XP/2003: Необходимо Windows 2000 SP4
или старше с Internet Explorer 6.0 или старше.
Ядро Windows NT/95/98/ME: CSP 3.0 не поддерживает (см.
КриптоПро CSP
2.0 ).
Ядро Solaris: 9 Update 4 или выше.
Ядро FreeBSD: FreeBSD 5.2 или выше
Ядро Linux: RedHat 7.3, RedHad 9.0.
Что Вы
думаете по поводу данной статьи? |
Закажите CD c Крипто-Про CSP |