macos信息采集器appledataharvester-3

1.src/Utils/Crypto.cpp

#include "Crypto.hpp"

#include "Logger.hpp"

#include <openssl/evp.h>

#include <openssl/aes.h>

#include <openssl/rand.h>

#include <openssl/sha.h>

#include <openssl/err.h>

#include <sstream>

#include <iomanip>

#include <fstream>

#include <stdexcept>

class DataEncryptor::Impl {

public:

Impl() {

// 初始化OpenSSL

OpenSSL_add_all_algorithms();

ERR_load_crypto_strings();

}

~Impl() {

// 清理OpenSSL

EVP_cleanup();

ERR_free_strings();

}

};

DataEncryptor::DataEncryptor(const std::string& keyFile)

: pImpl_(std::make_unique<Impl>())

, keyFilePath_(keyFile) {

LOG_INFO("DataEncryptor initialized");

// 尝试加载密钥

if (!keyFile.empty()) {

loadKey(keyFile);

} else {

// 使用默认密钥文件

keyFilePath_ = "encryption_key.bin";

loadKey(keyFilePath_);

}

}

DataEncryptor::~DataEncryptor() {

LOG_INFO("DataEncryptor destroyed");

}

bool DataEncryptor::hasKey() const {

return keyLoaded_;

}

void DataEncryptor::setAlgorithm(Algorithm algorithm) {

currentAlgorithm_ = algorithm;

LOG_INFO("Encryption algorithm set to: {}", static_cast<int>(algorithm));

}

DataEncryptor::Algorithm DataEncryptor::getAlgorithm() const {

return currentAlgorithm_;

}

std::string DataEncryptor::encrypt(const std::string& plaintext) {

if (!keyLoaded_) {

LOG_ERROR("No encryption key loaded");

return "";

}

try {

std::vector<uint8_t> plaintextVec(plaintext.begin(), plaintext.end());

std::vector<uint8_t> ciphertextVec = encryptData(plaintextVec);

if (ciphertextVec.empty()) {

LOG_ERROR("Encryption failed");

return "";

}

// 转换为base64

std::string ciphertext = CryptoUtils::base64Encode(ciphertextVec);

LOG_DEBUG("Encrypted {} bytes to {} bytes (base64)",

plaintext.size(), ciphertext.size());

return ciphertext;

} catch (const std::exception& e) {

LOG_ERROR("Exception during encryption: {}", e.what());

return "";

}

}

std::string DataEncryptor::decrypt(const std::string& ciphertext) {

if (!keyLoaded_) {

LOG_ERROR("No encryption key loaded");

return "";

}

try {

// 从base64解码

std::vector<uint8_t> ciphertextVec = CryptoUtils::base64Decode(ciphertext);

if (ciphertextVec.empty()) {

LOG_ERROR("Failed to decode base64 ciphertext");

return "";

}

std::vector<uint8_t> plaintextVec = decryptData(ciphertextVec);

if (plaintextVec.empty()) {

LOG_ERROR("Decryption failed");

return "";

}

std::string plaintext(plaintextVec.begin(), plaintextVec.end());

LOG_DEBUG("Decrypted {} bytes (base64) to {} bytes",

ciphertext.size(), plaintext.size());

return plaintext;

} catch (const std::exception& e) {

LOG_ERROR("Exception during decryption: {}", e.what());

return "";

}

}

bool DataEncryptor::encryptFile(const std::string& inputFile,

const std::string& outputFile) {

try {

// 读取文件

std::ifstream inFile(inputFile, std::ios::binary);

if (!inFile.is_open()) {

LOG_ERROR("Failed to open input file: {}", inputFile);

return false;

}

std::string plaintext((std::istreambuf_iterator<char>(inFile)),

std::istreambuf_iterator<char>());

inFile.close();

// 加密

std::string ciphertext = encrypt(plaintext);

if (ciphertext.empty()) {

LOG_ERROR("Failed to encrypt file content");

return false;

}

// 写入文件

std::ofstream outFile(outputFile, std::ios::binary);

if (!outFile.is_open()) {

LOG_ERROR("Failed to open output file: {}", outputFile);

return false;

}

outFile << ciphertext;

outFile.close();

LOG_INFO("File encrypted: {} -> {} ({} bytes)",

inputFile, outputFile, ciphertext.size());

return true;

} catch (const std::exception& e) {

LOG_ERROR("Exception during file encryption: {}", e.what());

return false;

}

}

bool DataEncryptor::decryptFile(const std::string& inputFile,

const std::string& outputFile) {

try {

// 读取文件

std::ifstream inFile(inputFile, std::ios::binary);

if (!inFile.is_open()) {

LOG_ERROR("Failed to open input file: {}", inputFile);

return false;

}

std::string ciphertext((std::istreambuf_iterator<char>(inFile)),

std::istreambuf_iterator<char>());

inFile.close();

// 解密

std::string plaintext = decrypt(ciphertext);

if (plaintext.empty()) {

LOG_ERROR("Failed to decrypt file content");

return false;

}

// 写入文件

std::ofstream outFile(outputFile, std::ios::binary);

if (!outFile.is_open()) {

LOG_ERROR("Failed to open output file: {}", outputFile);

return false;

}

outFile << plaintext;

outFile.close();

LOG_INFO("File decrypted: {} -> {} ({} bytes)",

inputFile, outputFile, plaintext.size());

return true;

} catch (const std::exception& e) {

LOG_ERROR("Exception during file decryption: {}", e.what());

return false;

}

}

bool DataEncryptor::encryptAndSave(const std::string& data,

const std::string& filename) {

try {

// 加密数据

std::string encryptedData = encrypt(data);

if (encryptedData.empty()) {

LOG_ERROR("Failed to encrypt data");

return false;

}

// 添加加密信息头

std::stringstream header;

header << "ENCv" << VERSION << "\n";

header << "ALG:" << static_cast<int>(currentAlgorithm_) << "\n";

header << "SIZE:" << data.size() << "\n";

header << "\n"; // 空行分隔头部和数据

std::string finalData = header.str() + encryptedData;

// 保存文件

std::ofstream file(filename, std::ios::binary);

if (!file.is_open()) {

LOG_ERROR("Failed to open file for writing: {}", filename);

return false;

}

file << finalData;

file.close();

LOG_INFO("Encrypted data saved to: {} ({} bytes)",

filename, finalData.size());

return true;

} catch (const std::exception& e) {

LOG_ERROR("Exception in encryptAndSave: {}", e.what());

return false;

}

}

std::string DataEncryptor::loadAndDecrypt(const std::string& filename) {

try {

// 读取文件

std::ifstream file(filename, std::ios::binary);

if (!file.is_open()) {

LOG_ERROR("Failed to open file: {}", filename);

return "";

}

std::string content((std::istreambuf_iterator<char>(file)),

std::istreambuf_iterator<char>());

file.close();

// 解析头部

size_t headerEnd = content.find("\n\n");

if (headerEnd == std::string::npos) {

LOG_ERROR("Invalid encrypted file format");

return "";

}

std::string header = content.substr(0, headerEnd);

std::string encryptedData = content.substr(headerEnd + 2);

// 解析版本

if (header.find("ENCv") != 0) {

LOG_ERROR("Invalid encryption header");

return "";

}

// 解密数据

std::string plaintext = decrypt(encryptedData);

LOG_INFO("Decrypted data loaded from: {} ({} bytes)",

filename, plaintext.size());

return plaintext;

} catch (const std::exception& e) {

LOG_ERROR("Exception in loadAndDecrypt: {}", e.what());

return "";

}

}

bool DataEncryptor::generateKey(const std::string& password) {

try {

// 生成随机盐值

keyInfo_.salt = generateRandom(SALT_SIZE);

// 派生密钥

if (!password.empty()) {

keyInfo_.key = deriveKey(password, keyInfo_.salt);

} else {

// 生成随机密钥

keyInfo_.key = generateRandom(KEY_SIZE);

}

// 生成随机IV

keyInfo_.iv = generateRandom(IV_SIZE);

keyInfo_.algorithm = currentAlgorithm_;

keyInfo_.version = VERSION;

keyLoaded_ = true;

LOG_INFO("Encryption key generated (algorithm: {})",

static_cast<int>(currentAlgorithm_));

return true;

} catch (const std::exception& e) {

LOG_ERROR("Exception during key generation: {}", e.what());

return false;

}

}

bool DataEncryptor::loadKey(const std::string& keyFile) {

try {

std::string filename = keyFile.empty() ? keyFilePath_ : keyFile;

std::ifstream file(filename, std::ios::binary);

if (!file.is_open()) {

LOG_WARN("Key file not found: {}", filename);

return generateKey(); // 自动生成新密钥

}

// 读取密钥文件

std::vector<uint8_t> keyData((std::istreambuf_iterator<char>(file)),

std::istreambuf_iterator<char>());

file.close();

if (keyData.size() < sizeof(KeyInfo)) {

LOG_ERROR("Invalid key file size");

return false;

}

// 解析密钥信息(简化版本)

// 实际应该使用更安全的序列化方式

size_t offset = 0;

// 读取版本

uint32_t version = *reinterpret_cast<uint32_t*>(&keyData[offset]);

offset += sizeof(uint32_t);

if (version != VERSION) {

LOG_ERROR("Unsupported key file version: {}", version);

return false;

}

// 读取算法

uint32_t algorithm = *reinterpret_cast<uint32_t*>(&keyData[offset]);

offset += sizeof(uint32_t);

keyInfo_.algorithm = static_cast<Algorithm>(algorithm);

// 读取密钥大小

uint32_t keySize = *reinterpret_cast<uint32_t*>(&keyData[offset]);

offset += sizeof(uint32_t);

// 读取密钥

keyInfo_.key.resize(keySize);

std::copy(keyData.begin() + offset,

keyData.begin() + offset + keySize,

keyInfo_.key.begin());

offset += keySize;

// 读取IV大小

uint32_t ivSize = *reinterpret_cast<uint32_t*>(&keyData[offset]);

offset += sizeof(uint32_t);

// 读取IV

keyInfo_.iv.resize(ivSize);

std::copy(keyData.begin() + offset,

keyData.begin() + offset + ivSize,

keyInfo_.iv.begin());

offset += ivSize;

// 读取盐值大小

uint32_t saltSize = *reinterpret_cast<uint32_t*>(&keyData[offset]);

offset += sizeof(uint32_t);

// 读取盐值

keyInfo_.salt.resize(saltSize);

std::copy(keyData.begin() + offset,

keyData.begin() + offset + saltSize,

keyInfo_.salt.begin());

keyInfo_.version = version;

keyLoaded_ = true;

LOG_INFO("Encryption key loaded from: {}", filename);

return true;

} catch (const std::exception& e) {

LOG_ERROR("Exception during key loading: {}", e.what());

return false;

}

}

bool DataEncryptor::saveKey(const std::string& keyFile) {

try {

if (!keyLoaded_) {

LOG_ERROR("No key to save");

return false;

}

std::string filename = keyFile.empty() ? keyFilePath_ : keyFile;

std::ofstream file(filename, std::ios::binary);

if (!file.is_open()) {

LOG_ERROR("Failed to open key file for writing: {}", filename);

return false;

}

// 写入密钥信息(简化版本)

file.write(reinterpret_cast<const char*>(&keyInfo_.version), sizeof(uint32_t));

uint32_t algorithm = static_cast<uint32_t>(keyInfo_.algorithm);

file.write(reinterpret_cast<const char*>(&algorithm), sizeof(uint32_t));

uint32_t keySize = static_cast<uint32_t>(keyInfo_.key.size());

file.write(reinterpret_cast<const char*>(&keySize), sizeof(uint32_t));

file.write(reinterpret_cast<const char*>(keyInfo_.data()), keySize);

uint32_t ivSize = static_cast<uint32_t>(keyInfo_.iv.size());

file.write(reinterpret_cast<const char*>(&ivSize), sizeof(uint32_t));

file.write(reinterpret_cast<const char*>(keyInfo_.iv.data()), ivSize);

uint32_t saltSize = static_cast<uint32_t>(keyInfo_.salt.size());

file.write(reinterpret_cast<const char*>(&saltSize), sizeof(uint32_t));

file.write(reinterpret_cast<const char*>(keyInfo_.salt.data()), saltSize);

file.close();

LOG_INFO("Encryption key saved to: {}", filename);

return true;

} catch (const std::exception& e) {

LOG_ERROR("Exception during key saving: {}", e.what());

return false;

}

}

std::vector<uint8_t> DataEncryptor::deriveKey(const std::string& password,

const std::vector<uint8_t>& salt) {

std::vector<uint8_t> key(KEY_SIZE);

if (PKCS5_PBKDF2_HMAC(password.c_str(), password.length(),

salt.data(), salt.size(),

100000, // 迭代次数

EVP_sha256(),

KEY_SIZE, key.data()) != 1) {

LOG_ERROR("Failed to derive key from password");

throw std::runtime_error("Key derivation failed");

}

return key;

}

std::vector<uint8_t> DataEncryptor::generateRandom(size_t size) {

std::vector<uint8_t> randomBytes(size);

if (RAND_bytes(randomBytes.data(), size) != 1) {

LOG_ERROR("Failed to generate random bytes");

throw std::runtime_error("Random generation failed");

}

return randomBytes;

}

std::vector<uint8_t> DataEncryptor::encryptData(const std::vector<uint8_t>& plaintext) {

switch (currentAlgorithm_) {

case Algorithm::AES_256_GCM:

case Algorithm::AES_256_CBC:

return encryptAES(plaintext);

case Algorithm::CHACHA20_POLY1305:

return encryptChaCha20(plaintext);

default:

LOG_ERROR("Unsupported encryption algorithm");

return {};

}

}

std::vector<uint8_t> DataEncryptor::decryptData(const std::vector<uint8_t>& ciphertext) {

switch (currentAlgorithm_) {

case Algorithm::AES_256_GCM:

case Algorithm::AES_256_CBC:

return decryptAES(ciphertext);

case Algorithm::CHACHA20_POLY1305:

return decryptChaCha20(ciphertext);

default:

LOG_ERROR("Unsupported encryption algorithm");

return {};

}

}

std::vector<uint8_t> DataEncryptor::encryptAES(const std::vector<uint8_t>& plaintext) {

EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();

if (!ctx) {

LOG_ERROR("Failed to create cipher context");

return {};

}

std::vector<uint8_t> ciphertext(plaintext.size() + EVP_MAX_BLOCK_LENGTH);

int len = 0;

int ciphertextLen = 0;

try {

const EVP_CIPHER* cipher = nullptr;

if (currentAlgorithm_ == Algorithm::AES_256_GCM) {

cipher = EVP_aes_256_gcm();

} else {

cipher = EVP_aes_256_cbc();

}

if (!cipher) {

throw std::runtime_error("Unsupported AES cipher");

}

if (EVP_EncryptInit_ex(ctx, cipher, nullptr,

keyInfo_.key.data(), keyInfo_.iv.data()) != 1) {

throw std::runtime_error("Encryption initialization failed");

}

if (EVP_EncryptUpdate(ctx, ciphertext.data(), &len,

plaintext.data(), plaintext.size()) != 1) {

throw std::runtime_error("Encryption update failed");

}

ciphertextLen = len;

if (EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &len) != 1) {

throw std::runtime_error("Encryption finalization failed");

}

ciphertextLen += len;

ciphertext.resize(ciphertextLen);

} catch (const std::exception& e) {

LOG_ERROR("AES encryption error: {}", e.what());

ciphertext.clear();

}

EVP_CIPHER_CTX_free(ctx);

return ciphertext;

}

std::vector<uint8_t> DataEncryptor::decryptAES(const std::vector<uint8_t>& ciphertext) {

EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();

if (!ctx) {

LOG_ERROR("Failed to create cipher context");

return {};

}

std::vector<uint8_t> plaintext(ciphertext.size() + EVP_MAX_BLOCK_LENGTH);

int len = 0;

int plaintextLen = 0;

try {

const EVP_CIPHER* cipher = nullptr;

if (currentAlgorithm_ == Algorithm::AES_256_GCM) {

cipher = EVP_aes_256_gcm();

} else {

cipher = EVP_aes_256_cbc();

}

if (!cipher) {

throw std::runtime_error("Unsupported AES cipher");

}

if (EVP_DecryptInit_ex(ctx, cipher, nullptr,

keyInfo_.key.data(), keyInfo_.iv.data()) != 1) {

throw std::runtime_error("Decryption initialization failed");

}

if (EVP_DecryptUpdate(ctx, plaintext.data(), &len,

ciphertext.data(), ciphertext.size()) != 1) {

throw std::runtime_error("Decryption update failed");

}

plaintextLen = len;

if (EVP_DecryptFinal_ex(ctx, plaintext.data() + len, &len) != 1) {

throw std::runtime_error("Decryption finalization failed");

}

plaintextLen += len;

plaintext.resize(plaintextLen);

} catch (const std::exception& e) {

LOG_ERROR("AES decryption error: {}", e.what());

plaintext.clear();

}

EVP_CIPHER_CTX_free(ctx);

return plaintext;

}

std::vector<uint8_t> DataEncryptor::encryptChaCha20(const std::vector<uint8_t>& plaintext) {

// 简化实现,实际应该使用OpenSSL的ChaCha20-Poly1305

LOG_WARN("ChaCha20 encryption not fully implemented");

return encryptAES(plaintext); // 临时使用AES

}

std::vector<uint8_t> DataEncryptor::decryptChaCha20(const std::vector<uint8_t>& ciphertext) {

// 简化实现,实际应该使用OpenSSL的ChaCha20-Poly1305

LOG_WARN("ChaCha20 decryption not fully implemented");

return decryptAES(ciphertext); // 临时使用AES

}

DataEncryptor::EncryptionInfo DataEncryptor::getEncryptionInfo() const {

EncryptionInfo info;

info.algorithm = currentAlgorithm_;

info.keySize = KEY_SIZE;

info.ivSize = IV_SIZE;

info.tagSize = TAG_SIZE;

info.authenticated = (currentAlgorithm_ == Algorithm::AES_256_GCM ||

currentAlgorithm_ == Algorithm::CHACHA20_POLY1305);

switch (currentAlgorithm_) {

case Algorithm::AES_256_GCM:

info.algorithmName = "AES-256-GCM";

break;

case Algorithm::CHACHA20_POLY1305:

info.algorithmName = "ChaCha20-Poly1305";

break;

case Algorithm::AES_256_CBC:

info.algorithmName = "AES-256-CBC";

break;

default:

info.algorithmName = "Unknown";

}

return info;

}

// CryptoUtils 命名空间实现

namespace CryptoUtils {

std::string sha256(const std::string& data) {

unsigned char hash[SHA256_DIGEST_LENGTH];

SHA256_CTX sha256;

SHA256_Init(&sha256);

SHA256_Update(&sha256, data.c_str(), data.size());

SHA256_Final(hash, &sha256);

std::stringstream ss;

for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {

ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];

}

return ss.str();

}

std::string sha256File(const std::string& filePath) {

std::ifstream file(filePath, std::ios::binary);

if (!file.is_open()) {

LOG_ERROR("Failed to open file for hashing: {}", filePath);

return "";

}

unsigned char hash[SHA256_DIGEST_LENGTH];

SHA256_CTX sha256;

SHA256_Init(&sha256);

char buffer[4096];

while (file.read(buffer, sizeof(buffer))) {

SHA256_Update(&sha256, buffer, file.gcount());

}

SHA256_Final(hash, &sha256);

file.close();

std::stringstream ss;

for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {

ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];

}

return ss.str();

}

std::string base64Encode(const std::vector<uint8_t>& data) {

BIO* b64 = BIO_new(BIO_f_base64());

BIO* bmem = BIO_new(BIO_s_mem());

b64 = BIO_push(b64, bmem);

BIO_write(b64, data.data(), data.size());

BIO_flush(b64);

BUF_MEM* bptr;

BIO_get_mem_ptr(b64, &bptr);

std::string result(bptr->data, bptr->length - 1); // 移除换行符

BIO_free_all(b64);

return result;

}

std::vector<uint8_t> base64Decode(const std::string& encoded) {

BIO* b64 = BIO_new(BIO_f_base64());

BIO* bmem = BIO_new_mem_buf(encoded.c_str(), encoded.length());

bmem = BIO_push(b64, bmem);

std::vector<uint8_t> decoded(encoded.length());

int len = BIO_read(bmem, decoded.data(), encoded.length());

BIO_free_all(bmem);

if (len > 0) {

decoded.resize(len);

return decoded;

}

return {};

}

std::string hexEncode(const std::vector<uint8_t>& data) {

std::stringstream ss;

for (const auto& byte : data) {

ss << std::hex << std::setw(2) << std::setfill('0') << (int)byte;

}

return ss.str();

}

std::vector<uint8_t> hexDecode(const std::string& encoded) {

if (encoded.length() % 2 != 0) {

return {};

}

std::vector<uint8_t> decoded(encoded.length() / 2);

for (size_t i = 0; i < encoded.length(); i += 2) {

std::string byteString = encoded.substr(i, 2);

uint8_t byte = static_cast<uint8_t>(std::stoul(byteString, nullptr, 16));

decoded[i / 2] = byte;

}

return decoded;

}

std::string generateRandomString(size_t length) {

static const char alphanum[] =

"0123456789"

"ABCDEFGHIJKLMNOPQRSTUVWXYZ"

"abcdefghijklmnopqrstuvwxyz";

std::string result;

result.reserve(length);

for (size_t i = 0; i < length; ++i) {

result.push_back(alphanum[rand() % (sizeof(alphanum) - 1)]);

}

return result;

}

std::vector<uint8_t> generateRandomBytes(size_t count) {

std::vector<uint8_t> bytes(count);

if (RAND_bytes(bytes.data(), count) != 1) {

LOG_ERROR("Failed to generate random bytes");

throw std::runtime_error("Random generation failed");

}

return bytes;

}

bool constantTimeCompare(const std::string& a, const std::string& b) {

if (a.length() != b.length()) {

return false;

}

uint8_t result = 0;

for (size_t i = 0; i < a.length(); i++) {

result |= a[i] ^ b[i];

}

return result == 0;

}

bool constantTimeCompare(const std::vector<uint8_t>& a,

const std::vector<uint8_t>& b) {

if (a.size() != b.size()) {

return false;

}

uint8_t result = 0;

for (size_t i = 0; i < a.size(); i++) {

result |= a[i] ^ b[i];

}

return result == 0;

}

bool checkPasswordStrength(const std::string& password) {

if (password.length() < 8) {

return false;

}

bool hasLower = false;

bool hasUpper = false;

bool hasDigit = false;

bool hasSpecial = false;

for (char c : password) {

if (std::islower(c)) hasLower = true;

else if (std::isupper(c)) hasUpper = true;

else if (std::isdigit(c)) hasDigit = true;

else if (!std::isspace(c)) hasSpecial = true;

}

// 至少需要3种类型的字符

int typeCount = (hasLower ? 1 : 0) + (hasUpper ? 1 : 0) +

(hasDigit ? 1 : 0) + (hasSpecial ? 1 : 0);

return typeCount >= 3;

}

}

相关推荐
浩浩测试一下2 小时前
WAF绕过之编码绕过特性篇
计算机网络·web安全·网络安全·网络攻击模型·安全威胁分析·安全架构
川川菜鸟3 小时前
Claude Code 安装与配置完整指南(Mac)
macos
WarmSword4 小时前
mac上用cursor/vscode调试root权限进程
c++·ide·vscode·macos·mac
Magnum Lehar5 小时前
macos的信息采集器appledataHarvester-2
macos·网络安全·系统安全
echo-niuben6 小时前
macOS 端已如何正常安装并配置XcodeBuildMCP ?
macos
刘某某.7 小时前
Mac上缺失宋体字体,只有宋体-简
macos
枷锁—sha8 小时前
【CTFshow-pwn系列】06_前置基础【pwn 035】详解:利用 SIGSEGV 信号处理机制
java·开发语言·安全·网络安全·信号处理
Tom·Ge8 小时前
在macOS上安装OpenClaw并实现Chrome网站自动化测试
chrome·macos·策略模式
勒索病毒前线8 小时前
深度硬核|.xr勒索病毒逆向分析与数据救援实战指南(附IOCs排查脚本)
网络安全·黑客攻击·勒索病毒·网络攻击溯源·.xr后缀病毒