//------------------------------------------------------------------------------------------------------------- // Данный пример демонстрирует использование объекта хэша PRFKEYMAT (CALG_GR3411_PRFKEYMAT, // CALG_GR3411_2012_256_PRFKEYMAT и CALG_GR3411_2012_512_PRFKEYMAT) для получения последовательности // псевдослучайных данных произвольной длины, а также для получения ключей CALG_G28147 и CALG_SYMMETRIC_512. //------------------------------------------------------------------------------------------------------------- static void HandleError(char *s); int main() { //------------------------------------------------------------------------ // Объявление переменных. HCRYPTPROV hProv = 0; HCRYPTKEY hPrfKey = 0; HCRYPTHASH hPrfHash = 0; CRYPT_DATA_BLOB prfSeedBlob; BYTE pbPrfSeedData[] = { 0x11, 0x22, 0x33, 0x44 }; BYTE pbDataFirst[10]; DWORD cbDataFirst = 0; HCRYPTKEY hDerivedKey256 = 0; BYTE pbDataSecond[100]; DWORD cbDataSecond = 0; HCRYPTKEY hDerivedKey512 = 0; //------------------------------------------------------------------------ // Получение дескриптора контекста криптографического провайдера. if(CryptAcquireContext( &hProv, NULL, NULL, PROV_GOST_2012_256, CRYPT_VERIFYCONTEXT)) { printf("CSP context acquired.\n"); } else { HandleError("Error during CryptAcquireContext."); } //------------------------------------------------------------------------ // Генерация ключа для PRF. if(CryptGenKey( hProv, CALG_G28147, 0, &hPrfKey)) { printf("PRF key is created. \n"); } else { HandleError("Error during CryptGenKey."); } //------------------------------------------------------------------------ // Создание объекта хэша PRF. if(CryptCreateHash( hProv, CALG_GR3411_2012_256_PRFKEYMAT, hPrfKey, 0, &hPrfHash)) { printf("PRF hash is created. \n"); } else { HandleError("Error during CryptCreateHash."); } //------------------------------------------------------------------------ // Устанавливаем seed для PRF. prfSeedBlob.pbData = pbPrfSeedData; prfSeedBlob.cbData = sizeof(pbPrfSeedData); if(CryptSetHashParam( hPrfHash, HP_PRFKEYMAT_SEED, (LPBYTE)&prfSeedBlob, 0)) { printf("PRF seed is set. \n"); } else { HandleError("Error during CryptSetHashParam."); } //------------------------------------------------------------------------ // Получаем последовательность данных необходимой длины. cbDataFirst = sizeof(pbDataFirst); if(CryptGetHashParam( hPrfHash, HP_HASHVAL, pbDataFirst, &cbDataFirst, 0)) { printf("First part of data produced. \n"); } else { HandleError("Error during CryptGetHashParam."); } //------------------------------------------------------------------------ // Получаем ключ 256 бит. if(CryptDeriveKey( hProv, CALG_G28147, hPrfHash, 0, &hDerivedKey256)) { printf("256-bit key derived. \n"); } else { HandleError("Error during CryptDeriveKey."); } //------------------------------------------------------------------------ // Получаем еще последовательность данных необходимой длины. cbDataSecond = sizeof(pbDataSecond); if(CryptGetHashParam( hPrfHash, HP_HASHVAL, pbDataSecond, &cbDataSecond, 0)) { printf("Second part of data produced. \n"); } else { HandleError("Error during CryptGetHashParam."); } //------------------------------------------------------------------------ // Получаем ключ 512 бит. if(CryptDeriveKey( hProv, CALG_SYMMETRIC_512, hPrfHash, 0, &hDerivedKey512)) { printf("512-bit key derived. \n"); } else { HandleError("Error during CryptDeriveKey."); } //------------------------------------------------------------------------ // Освобождение памяти. if (hDerivedKey256) { CryptDestroyKey(hDerivedKey256); } if (hDerivedKey512) { CryptDestroyKey(hDerivedKey512); } if (hPrfHash) { CryptDestroyHash(hPrfHash); } if (hPrfKey) { CryptDestroyKey(hPrfKey); } if (hProv) { CryptReleaseContext(hProv, 0); } return 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: не поддерживает.