//-------------------------------------------------------------------- // Пример создания сессионного ключа, основанного на хэше, рассчитанного // из пароля пользователя. Пароль вводится в процессе работы программы. // Замечание: под win32 рекомендуется использовать _s аналоги CRT функций. //-------------------------------------------------------------------- #define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) static void HandleError(const char *s); static void CleanUp(void); static HCRYPTPROV hCryptProv = 0; static HCRYPTKEY hKey = 0; static HCRYPTHASH hHash = 0; int main(void) { //-------------------------------------------------------------------- // Пароль из которого будет получен сессионный ключ. CHAR szPassword[] = "123456\0"; DWORD dwLength; dwLength = (DWORD)strlen(szPassword); //-------------------------------------------------------------------- // Получение дескриптора контекста криптографического провайдера. if(CryptAcquireContext( &hCryptProv, NULL, NULL, PROV_GOST_2012_256, CRYPT_VERIFYCONTEXT)) { printf("A context has been acquired. \n"); } else { HandleError("Error during CryptAcquireContext!"); } //-------------------------------------------------------------------- // Создание пустого объекта хэширования. if(CryptCreateHash( hCryptProv, CALG_GR3411_2012_256, 0, 0, &hHash)) { printf("An empty hash object has been created. \n"); } else { HandleError("Error during CryptCreateHash!"); } //-------------------------------------------------------------------- // Хэширование строки пароля. if(CryptHashData( hHash, (BYTE *)szPassword, dwLength, 0)) { printf("The password has been hashed. \n"); } else { HandleError("Error during CryptHashData!"); } //-------------------------------------------------------------------- // Создание сессионного ключа, основанного на хэше, полученного из пароля. if(CryptDeriveKey( hCryptProv, CALG_G28147, hHash, CRYPT_EXPORTABLE, &hKey)) { printf("The key has been derived. \n"); } else { HandleError("Error during CryptDeriveKey!"); } CleanUp(); printf("The program to derive a key completed without error. \n"); return 0; } void CleanUp(void) { if(hHash) CryptDestroyHash(hHash); // Уничтожение сессионного ключа. if(hKey) CryptDestroyKey(hKey); // Освобождение дескриптора провайдера. 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.