#include "EncryptionManager.h" EncryptionManager::EncryptionManager() :keyReady(false) { if (sodium_init() < 0) { throw std::runtime_error("libsodium init failed"); } keyReady = false; generateKeys(); } std::vector EncryptionManager::encrypt(const std::vector& raw) { std::vector crypt(raw.size()); // Generowanie kluczy // generateKeys(); if (crypto_stream_chacha20_ietf_xor_ic( reinterpret_cast(crypt.data()), reinterpret_cast(raw.data()), static_cast(raw.size()), nonce.data(), 0, key.data()) != 0) { throw std::runtime_error("crypto_stream_chacha20_ietf_xor_ic failed"); } return crypt; } void EncryptionManager::generateKeys() { if (keyReady) return; //randombytes_buf(key.data(), key.size()); crypto_stream_chacha20_ietf_keygen(key.data()); randombytes_buf(nonce.data(), nonce.size()); keyReady = true; } void EncryptionManager::saveKey(const std::string& path, bool hpp) { const int sig = SIGNATURE_KEY_FILE; const short ver = VERSION; // Wygeneruj time stamp std::time_t now = std::time(nullptr); const int time = static_cast(now); // Wygeneruj crc kluczy std::vector keyVec(reinterpret_cast(key.data()), reinterpret_cast(key.data()) + key.size()); std::vector nonceVec(reinterpret_cast(nonce.data()), reinterpret_cast(nonce.data()) + nonce.size()); const uint64_t crcKey = XXH64(keyVec.data(), keyVec.size(), VERSION); const uint64_t crcNonce = XXH64(nonceVec.data(), nonceVec.size(), VERSION); // Zapisz ten śmietnik do pliku KEY std::ofstream file(path + ".key", std::ios::binary); if (!file) { std::cout << "Failed to save encryption key to file" << std::endl; } file.write(reinterpret_cast(&sig), sizeof(sig)); file.write(reinterpret_cast(&ver), sizeof(ver)); file.write(reinterpret_cast(&time), sizeof(time)); file.write(reinterpret_cast(keyVec.data()), keyVec.size()); file.write(reinterpret_cast(&crcKey), sizeof(crcKey)); file.write(reinterpret_cast(nonceVec.data()), nonceVec.size()); file.write(reinterpret_cast(&crcNonce), sizeof(crcNonce)); file.close(); if (hpp) {saveCppHeadFile(path);} } // Generowanie pliku nagłówkowego CPP z kluczem i nonce void EncryptionManager::saveCppHeadFile(const std::string& path) { std::vector keyVec(key.begin(), key.end()); std::vector nonceVec(nonce.begin(), nonce.end()); const std::string headerText = "// Plik wygenerowany przy wykorzystaniu exPAK\n\n" "// Klucz deszyfrujący\n" "const std::array key{" + toHex(keyVec) + "};\n\n" "// Ciąg nonce\n" "const std::array nonce{" + toHex(nonceVec) + "}; "; std::ofstream file(path + ".hh"); file << headerText; file.close(); } std::string EncryptionManager::toHex(const std::vector& data) { std::string bytes; int sk = data.size(); int skp = 1; for (const auto& b : data) { std::stringstream ss; ss << "0x" << std::hex << std::uppercase << std::setw(2) << std::setfill('0') << static_cast(b); bytes += "'"; bytes += ss.str(); bytes += "'"; if (skp < sk) { bytes += ", "; skp++; } } return bytes; } // Wczytaj klucz void EncryptionManager::loadKey(const std::string& path) { std::ifstream file(path + ".key", std::ios::binary); int sig; short ver; int time; // Wczytaj file.read(reinterpret_cast(&sig), sizeof(sig)); file.read(reinterpret_cast(&ver), sizeof(ver)); // Sprawdź czy plik klucza jest poprawny if (sig != SIGNATURE_KEY_FILE || ver != VERSION) { throw std::runtime_error("Invalid key file!"); } std::vector keyVec(key.size()); std::vector nonceVec(nonce.size()); uint64_t crcKey; uint64_t crcNonce; file.read(reinterpret_cast(&time), sizeof(time)); file.read(keyVec.data(), keyVec.size()); file.read(reinterpret_cast(&crcKey), sizeof(crcKey)); file.read(nonceVec.data(), nonceVec.size()); file.read(reinterpret_cast(&crcNonce), sizeof(crcNonce)); // Sprawdź integralność klucza if (XXH64(keyVec.data(), keyVec.size(), VERSION) != crcKey || XXH64(nonceVec.data(), nonceVec.size(), VERSION) != crcNonce) { throw std::runtime_error("Key integrity error!"); } file.close(); // Przekonwertuj vector na array key = toArray(keyVec); nonce = toArray(nonceVec); } // Deszyfracja std::vector EncryptionManager::decrypt(const std::vector& crypt) { std::vector raw(crypt.size()); if (crypto_stream_chacha20_ietf_xor( reinterpret_cast(raw.data()), reinterpret_cast(crypt.data()), static_cast(crypt.size()), nonce.data(), key.data()) != 0) { throw std::runtime_error("Data decryption error!"); } return raw; }