#include #include #include using namespace std; void ErrorHandling(){ DWORD dw = GetLastError(); cout << "Error: " << hex << dw << endl; } int symmetricED() { // шифрование // хеширование // cryptderivekey // cryptencrypt string password = "#@$4&"; // секретные данные string data = "Hello, World!"; // что мы хотим зашифровать if (data.length() == 0) { // проверка входных данных на корректность cout << "Input data is wrong. Please, try again.\n"; return -1; } string encryptedData = data; // куда мы запихнём зашифрованные данные HCRYPTPROV hProv; // дескриптор криптопровайдера HCRYPTHASH hHash; // дескриптор хеша HCRYPTKEY hKey; // дескриптор криптографического ключа DWORD dataLength = (DWORD)data.length(); // длина входной строки cout << "\t\tInput data\n"; cout << "Data: " << data << endl; cout << "Data length: " << data.length() << endl; // CryptAcquireContext получает дескриптор используемого в данный момент ключевого контейнера, находящегося в определенном CSP. if (CryptAcquireContext(&hProv,NULL,MS_DEF_PROV,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT)) { // хешируем данные для дальнейшей передачи в CryptDeriveKey if (CryptCreateHash(hProv,CALG_MD5,0,0,&hHash)) { if (CryptHashData(hHash,(BYTE*)password.c_str(),password.length(),0)) { // Функция CryptDeriveKey генерит криптографические сессионные ключи, получая их из исходных данных // Функция CryptDeriveKey создает ключ, получая его из пароля. if (CryptDeriveKey(hProv,CALG_RC4,hHash,0,&hKey)) { cout << "\t\t Encryption\n"; // шифруем данные if (CryptEncrypt(hKey,0,TRUE,0, (BYTE *)encryptedData.c_str(),&dataLength,data.length())) { cout << "Encrypted successfully\n"; cout << "Encrypted string: " << encryptedData << endl; cout << "Encrypted data length:" << static_cast(dataLength) << endl; } else { ErrorHandling(); CryptDestroyKey(hKey); } cout << "\t\t Decryption\n"; // расшифровываем данные string decryptedData = encryptedData; if (CryptDecrypt(hKey,0,TRUE,0,(BYTE *)decryptedData.c_str(),&dataLength)) { cout << "Decrypted successfully\n"; cout << "Decrypted string: " << decryptedData << endl; cout << "Decrypted data length: " << static_cast(dataLength) << endl; } else { ErrorHandling(); CryptDestroyKey(hKey); } } else { ErrorHandling(); CryptDestroyHash(hHash); } } else { ErrorHandling(); CryptDestroyHash(hHash); } } else { ErrorHandling(); CryptReleaseContext(hProv,0); return -1; } } else { ErrorHandling(); return -1; } return 0; } int hybridED(){ string data = "Hello, World!"; // входная строка string encryptedData = data; DWORD dataLength = static_cast(data.length()); // её длина HCRYPTPROV hProv; LPCWSTR hName = L"Container"; // имя контейнера HCRYPTKEY hSessionKey, hExportKey; // ключ сессии и публичный HCRYPTKEY hImportKey; // ключ для импорта DWORD pbDataLen = 0; // длина массива для экспорта ключа if (!CryptAcquireContext(&hProv,hName,NULL,PROV_RSA_FULL,CRYPT_NEWKEYSET)) { ErrorHandling(); return -1; } // генерируем ключ сессии cout << "Generating session key\n"; if (!CryptGenKey(hProv,CALG_RC4, CRYPT_EXPORTABLE | CRYPT_ENCRYPT | CRYPT_DECRYPT, &hSessionKey)) { ErrorHandling(); return -1; } cout << "Session key has been generated\n"; // генерируем ключ для экспорта в данном контексте cout << "Generating export key\n"; if (!CryptGenKey(hProv,AT_KEYEXCHANGE,0,&hExportKey)) { ErrorHandling(); return -1; } if (!CryptGetUserKey(hProv,AT_KEYEXCHANGE,&hExportKey)) { ErrorHandling(); return -1; } cout << "Export key has been generated\n"; // рассчитываем длину для экспорта ключа if (!CryptExportKey(hSessionKey,hExportKey,SIMPLEBLOB,0,NULL,&pbDataLen)) { ErrorHandling(); return -1; } PBYTE exportKey = static_cast(malloc(pbDataLen)); ZeroMemory(exportKey,pbDataLen); // Экспортируем ключ шифрования if (!CryptExportKey(hSessionKey,hExportKey,SIMPLEBLOB,0, exportKey,&pbDataLen)) { ErrorHandling(); return -1; } cout << "Key has been exported\n"; cout << "Data encryption\n"; cout << "\t\tInput data\n"; cout << "Data: " << data << endl; cout << "Data length: " << data.length() << endl; if (!CryptEncrypt(hSessionKey,0,TRUE,0, (PBYTE) encryptedData.c_str(),&dataLength,data.length())) { ErrorHandling(); return -1; } else { cout << "Encrypted successfully\n"; cout << "Encrypted string: " << encryptedData << endl; cout << "Encrypted data length:" << static_cast(dataLength) << endl; } cout << "Data decryption\n"; cout << "Importing key\n"; if (!CryptImportKey(hProv,exportKey,pbDataLen,hExportKey,0,&hImportKey)) { ErrorHandling(); return -1; } cout << "Key has been imported successfully\n"; string decryptedData = encryptedData; if (CryptDecrypt(hImportKey,0,TRUE,0,(BYTE *) decryptedData.c_str(),&dataLength)) { cout << "Decrypted successfully\n"; cout << "Decrypted string: " << decryptedData << endl; cout << "Decrypted data length: " << static_cast(dataLength) << endl; } else { ErrorHandling(); return -1; } // освобождаем память if (hProv) { CryptAcquireContext(&hProv,hName,NULL,PROV_RSA_FULL,CRYPT_DELETEKEYSET); CryptReleaseContext(hProv,0); } if (hSessionKey) CryptDestroyKey(hSessionKey); if (hExportKey) CryptDestroyKey(hExportKey); return 0; // succeded } int main(){ cout << "\t\tSymmetric Encryption Decryption\n"; if (symmetricED() == 0) cout << "Successfully executed symmetric ED\n"; else cout << "Unsuccessfully executed symmetric ED\n"; cout << "\t\tHYDRID Encryption\n"; hybridED(); system("pause"); return 0; }