//-------------------------------------------------------------------- // В данном примере осуществляется хэширование строки, дублирование // полученного хэша. Затем осуществляется хэширование дополнительных // данных при помощи оригинального и дублированного хэша. //-------------------------------------------------------------------- static void HandleError(const 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: 6/7.
FreeBSD: 11/12, pfSense 2.x.
Linux: LSB 4.x (RHEL 5/6/7/8, SuSE 11SP4/12/15, Oracle Linux 5/6/7/8, CentOS 6/7/8, Ubuntu 14.04/16.04/18.04/19.10, Linux Mint 18/19, Fedora 28/29/30/31, Debian 8/9/10 и др.).
Solaris: 10/11.
Mac OS X: 10.9/10.10/10.11/10.12/10.13/10.14/10.15.
iOS: 8/9/10/11/12/13.
Sailfish: 2/3.
Windows: 7/8/8.1/10, Server 2008/2008R2/2012/2012R2/2016/2019.