Крипто-Про CSP |
//-------------------------------------------------------------------- // В этом примере реализованы создание подписи объекта функции хеширования // и проверка этой электронно-цифровой подписи. //-------------------------------------------------------------------- #define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) void HandleError(char *s); void main(void) { //------------------------------------------------------------- // Объявление и инициализация переменных. HCRYPTPROV hProv; BYTE *pbBuffer= (BYTE *)"The data that is to be hashed and signed."; DWORD dwBufferLen = (DWORD)(strlen((char *)pbBuffer)+1); HCRYPTHASH hHash; HCRYPTKEY hKey; HCRYPTKEY hPubKey; BYTE *pbKeyBlob; BYTE *pbSignature; DWORD dwSigLen; DWORD dwBlobLen; BYTE *pbHash; DWORD cbHash; FILE *signature; LPTSTR szDescription = "Test Data Description"; //-------------------------------------------------------------------- // Получение дескриптора контекста криптографического провайдера. if(CryptAcquireContext( &hProv, NULL, NULL, 75, 0)) { printf("CSP context acquired.\n"); } else { HandleError("Error during CryptAcquireContext."); } //-------------------------------------------------------------------- // Получение открытого ключа подписи. Этот открытый ключ будет // использоваться получателем хеша для проверки подписи. // В случае, когда получатель имеет доступ к открытому ключю // отправителя с помощью сертификата, этот шаг не нужен. if(CryptGetUserKey( hProv, AT_SIGNATURE, &hKey)) { printf("The signature key has been acquired. \n"); } else { HandleError("Error during CryptGetUserKey for signkey."); } //-------------------------------------------------------------------- // Экпорт открытого ключа. Здесь открытый ключ экспортируется в // PUBLICKEYBOLB для того, чтобы получатель подписанного хеша мог // проверить подпись. Этот BLOB может быть записан в файл и передан // другому пользователю. if(CryptExportKey( hKey, 0, PUBLICKEYBLOB, 0, NULL, &dwBlobLen)) { printf("Size of the BLOB for the public key determined. \n"); } else { HandleError("Error computing BLOB length."); } //-------------------------------------------------------------------- // Распределение памяти под pbKeyBlob. pbKeyBlob = (BYTE*)malloc(dwBlobLen); if(pbKeyBlob) { printf("Memory has been allocated for the BLOB. \n"); } else { HandleError("Out of memory. \n"); } //-------------------------------------------------------------------- // Сам экспорт в ключевой BLOB. if(CryptExportKey( hKey, 0, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen)) { printf("Contents have been written to the BLOB. \n"); } else { HandleError("Error during CryptExportKey."); } //-------------------------------------------------------------------- // Создание объекта функции хеширования. if(CryptCreateHash( hProv, CALG_GR3411, 0, 0, &hHash)) { printf("Hash object created. \n"); } else { HandleError("Error during CryptCreateHash."); } //-------------------------------------------------------------------- // Передача параметра HP_OID объекта функции хеширования. //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Определение размера BLOBа и распределение памяти. if(CryptGetHashParam(hHash, HP_OID, NULL, &cbHash, 0)) { printf("Size of the BLOB determined. \n"); } else { HandleError("Error computing BLOB length."); } pbHash = (BYTE*)malloc(cbHash); if(pbHash) { printf("Memory has been allocated for the pbHash. \n"); } else { HandleError("Out of memory. \n"); } //-------------------------------------------------------------------- // Копирование параметра HP_OID в pbHash. if(CryptGetHashParam(hHash, HP_OID, pbHash, &cbHash, 0)) { printf("Parameters have been written to the pbHash. \n"); } else { HandleError("Error during CryptGetHashParam."); } //-------------------------------------------------------------------- // Вычисление криптографического хеша буфера. if(CryptHashData( hHash, pbBuffer, dwBufferLen, 0)) { printf("The data buffer has been hashed.\n"); } else { HandleError("Error during CryptHashData."); } //-------------------------------------------------------------------- // Определение размера подписи и распределение памяти. dwSigLen= 0; if(CryptSignHash( hHash, AT_SIGNATURE, szDescription, 0, NULL, &dwSigLen)) { printf("Signature length %d found.\n",dwSigLen); } else { HandleError("Error during CryptSignHash."); } //-------------------------------------------------------------------- // Распределение памяти под буфер подписи. pbSignature = (BYTE *)malloc(dwSigLen); if(pbSignature) { printf("Memory allocated for the signature.\n"); } else { HandleError("Out of memory."); } //-------------------------------------------------------------------- // Подпись объекта функции хеширования. if(CryptSignHash( hHash, AT_SIGNATURE, szDescription, 0, pbSignature, &dwSigLen)) { printf("pbSignature is the hash signature.\n"); } else { HandleError("Error during CryptSignHash."); } signature = fopen( "signature.txt", "w+b" ); if(!signature) HandleError( "Problem opening the file\n" ); fwrite (pbSignature, 1, dwSigLen, signature); //-------------------------------------------------------------------- // Уничтожение объекта функции хеширования. if(hHash) CryptDestroyHash(hHash); printf("The hash object has been destroyed.\n"); printf("The signing phase of this program is completed.\n\n"); //-------------------------------------------------------------------- // Во второй части программы проверяется подпись. // Чаще всего проверка осуществляется в случае, когда различные // пользователи используют одну и ту же программу. Хеш, подпись, // а также PUBLICKEYBLOB могут быть прочитаны из файла, e-mail сообщения // или из другого источника. // Здесь используюся определенные ранее pbBuffer, pbSignature, // szDescription, pbKeyBlob и их длины. // Содержимое буфера pbBuffer представляет из себя некоторые // подписанные ранее данные. // Указатель szDescription на текст, описывающий данные, подписывается. // Это тот же самый текст описания, который был ранее передан // функции CryptSignHash. //-------------------------------------------------------------------- // Получение откытого ключа пользователя, который создал цифровую подпись, // и импортирование его в CSP с помощью функции CryptImportKey. Она // возвращает дескриптор открытого ключа в hPubKey. if(CryptImportKey( hProv, pbKeyBlob, dwBlobLen, 0, 0, &hPubKey)) { printf("The key has been imported.\n"); } else { HandleError("Public key import failed."); } //-------------------------------------------------------------------- // Создание нового объекта функции хеширования. if(CryptCreateHash( hProv, CALG_GR3411, 0, 0, &hHash)) { printf("The hash object has been recreated. \n"); } else { HandleError("Error during CryptCreateHash."); } //-------------------------------------------------------------------- // Установка параметра HP_OID. // По умолчанию провайдер работает на наборе параметров 1.2.643.2.2.30.1. // Без установки параметра HP_OID программа будет неверно работать, // если параметры хеширования не будут являться параметрами // по умолчанию. if(CryptSetHashParam( hHash, HP_OID, pbHash, 0)) { printf("The parameters have been set. \n"); } else { HandleError("Error during SetHashParam."); } //-------------------------------------------------------------------- // Вычисление криптографического хеша буфера. if(CryptHashData( hHash, pbBuffer, dwBufferLen, 0)) { printf("The new has been created.\n"); } else { HandleError("Error during CryptHashData."); } //-------------------------------------------------------------------- // Проверка цифровой подписи. if(CryptVerifySignature( hHash, pbSignature, dwSigLen, hPubKey, szDescription, 0)) { printf("The signature has been verified.\n"); } else { printf("Signature not validated!\n"); } //-------------------------------------------------------------------- // Освобождение памяти, необходимой для хранения подписи и для хранения // параметров объекта функции хеширования. if(pbSignature) free(pbSignature); if(pbHash) free(pbHash); //-------------------------------------------------------------------- // Уничтожение объекта функции хеширования. if(hHash) CryptDestroyHash(hHash); //-------------------------------------------------------------------- // Освобождение дескриптора провайдера. if(hProv) CryptReleaseContext(hProv, 0); } // Конец main
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.
Ядро Windows NT: не поддерживает.
Что Вы
думаете по поводу данной статьи? |
Закажите CD c Крипто-Про CSP |