//-------------------------------------------------------------------- // В данном примере осуществляется хэширование строки, дублирование // полученного хэша. Затем осуществляется хэширование дополнительных // данных при помощи оригинального и дублированного хэша. //-------------------------------------------------------------------- static void HandleError(char *s); static void CleanUp(void); static void Get_And_Print_Hash(HCRYPTHASH hHash); static HCRYPTPROV hCryptProv = 0; static HCRYPTHASH hOriginalHash = 0; static HCRYPTHASH hDuplicateHash = 0; int main(void) { // Получение дескриптора контекста криптографического провайдера. if(CryptAcquireContext( &hCryptProv, NULL, NULL, PROV_GOST_2012_256, CRYPT_VERIFYCONTEXT)) { printf("CryptAcquireContext succeeded. \n"); } else { HandleError("Error during CryptAcquireContext!"); } //-------------------------------------------------------------------- // Создание объекта функции хэширования. if(CryptCreateHash( hCryptProv, CALG_GR3411_2012_256, 0, 0, &hOriginalHash)) { printf("An empty hash object has been created. \n"); } else { HandleError("Error during CryptCreateHash."); } //-------------------------------------------------------------------- // Хэширование байтовой строки. if(CryptHashData( hOriginalHash, (BYTE*)"Some Common Data", sizeof("Some Common Data"), 0)) { printf("An original hash has been created. \n"); } else { HandleError("Error during CryptHashData."); } //-------------------------------------------------------------------- // Дублирование хэша. // Эта функция работает только в Windows 2000 и старше. if(CryptDuplicateHash( hOriginalHash, NULL, 0, &hDuplicateHash)) { printf("The hash has been duplicated. \n"); } else { HandleError("Error during CryptDuplicateHash."); } printf("The original hash -- phase 1.\n"); Get_And_Print_Hash(hOriginalHash); printf("The duplicate hash -- phase 1.\n"); Get_And_Print_Hash(hDuplicateHash); //-------------------------------------------------------------------- // Хэширование "Some Data" с оригинальным хэшем. if(CryptHashData( hOriginalHash, (BYTE*)"Some Data", sizeof("Some Data"), 0)) { printf("Additional data has been hashed with the original. \n"); } else { HandleError("Error during CryptHashData."); } //-------------------------------------------------------------------- // Хэширование "Other Data" с дублированным хэшем. if(CryptHashData( hDuplicateHash, (BYTE*)"Other Data", sizeof("Other Data"), 0)) { printf("More data has been hashed with the duplicate. \n"); } else { HandleError("Error during CryptHashData."); } printf("The original hash -- phase 2.\n"); Get_And_Print_Hash(hOriginalHash); printf("The duplicate hash -- phase 2.\n"); Get_And_Print_Hash(hDuplicateHash); CleanUp(); printf("The program ran to completion without error. \n"); return 0; } // Определение функции Get_And_Print_Hash. void Get_And_Print_Hash(HCRYPTHASH hOHash) { BYTE *pbHash; BYTE *pbHashSize; DWORD dwHashLen = sizeof(DWORD); DWORD i; HCRYPTHASH hHash=0; //-------------------------------------------------------------------- // Дублирование установленного хэша. // Эта функция работает только в Windows 2000 и старше. // Хэш продублирован для того, чтобы не изменять исходный хэш. if(!CryptDuplicateHash( hOHash, NULL, 0, &hHash)) { HandleError("Error during CryptDuplicateHash."); } pbHashSize =(BYTE *) malloc(dwHashLen); if(!pbHashSize) HandleError("Memory allocation failed."); if(CryptGetHashParam( hHash, HP_HASHSIZE, pbHashSize, &dwHashLen, 0)) { // Работает. Освобождение pbHashSize. free(pbHashSize); } else { free(pbHashSize); HandleError("CryptGetHashParam failed to get size."); } if(!CryptGetHashParam( hHash, HP_HASHVAL, NULL, &dwHashLen, 0)) { HandleError("CryptGetHashParam failed to get length."); } pbHash = (BYTE*)malloc(dwHashLen); if(!pbHash) HandleError("Allocation failed."); if(CryptGetHashParam( hHash, HP_HASHVAL, pbHash, &dwHashLen, 0)) { // Печать значения хэша. printf("The hash is: "); for(i = 0 ; i < dwHashLen ; i++) { printf("%2.2x ",pbHash[i]); } printf("\n"); free(pbHash); } else { free(pbHash); HandleError("Error during reading hash value."); } if(!CryptDestroyHash(hHash)) { HandleError("ERROR - CryptDestroyHash"); } } void CleanUp(void) { // Уничтожение оригинального хэша. if (hOriginalHash) CryptDestroyHash(hOriginalHash); printf("The original hash has been destroyed. \n"); // Уничтожение дублированного хэша. if (hDuplicateHash) CryptDestroyHash(hDuplicateHash); printf("The duplicate hash has been destroyed. \n"); // Освобождение CSP. if(hCryptProv) CryptReleaseContext(hCryptProv,0); } // Конец примера
AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Ядро Windows NT: не поддерживает.