-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCode.cpp
More file actions
100 lines (84 loc) · 3.73 KB
/
Code.cpp
File metadata and controls
100 lines (84 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <openssl/evp.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <pybind11/pybind11.h>
#include <vector>
#include <string>
#include <algorithm>
namespace py = pybind11;
class VaultEngine {
public:
/**
* Encrypts a string using AES-256-CBC.
* @param plaintext The sensitive data to encrypt.
* @param key A 32-character master key.
* @return A binary string containing [IV (16 bytes) + Ciphertext].
*/
std::string encrypt(const std::string& plaintext, const std::string& key) {
if (key.size() != 32) {
throw std::invalid_argument("Encryption key must be exactly 32 characters (256 bits).");
}
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
int len;
int ciphertext_len;
// Prepare buffer: plaintext size + block size for padding
std::vector<unsigned char> ciphertext(plaintext.size() + AES_BLOCK_SIZE);
unsigned char iv[AES_BLOCK_SIZE];
// Generate a cryptographically strong random IV
if (!RAND_bytes(iv, AES_BLOCK_SIZE)) {
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Failed to generate random IV.");
}
EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)key.c_str(), iv);
EVP_EncryptUpdate(ctx, ciphertext.data(), &len, (unsigned char*)plaintext.c_str(), (int)plaintext.size());
ciphertext_len = len;
EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &len);
ciphertext_len += len;
EVP_CIPHER_CTX_free(ctx);
// Prepend IV to the ciphertext so it can be retrieved during decryption
std::string result((char*)iv, AES_BLOCK_SIZE);
result.append((char*)ciphertext.data(), ciphertext_len);
return result;
}
/**
* Decrypts a string using AES-256-CBC.
* @param encrypted_data The binary string [IV + Ciphertext].
* @param key A 32-character master key.
* @return The decrypted plaintext string.
*/
std::string decrypt(const std::string& encrypted_data, const std::string& key) {
if (key.size() != 32) {
throw std::invalid_argument("Decryption key must be exactly 32 characters.");
}
if (encrypted_data.size() < AES_BLOCK_SIZE) {
throw std::runtime_error("Corrupted or invalid encrypted data.");
}
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
int len;
int plaintext_len;
// Extract IV from the first 16 bytes
unsigned char iv[AES_BLOCK_SIZE];
std::copy(encrypted_data.begin(), encrypted_data.begin() + AES_BLOCK_SIZE, iv);
// Extract the actual ciphertext
std::string ciphertext = encrypted_data.substr(AES_BLOCK_SIZE);
std::vector<unsigned char> plaintext(ciphertext.size());
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)key.c_str(), iv);
EVP_DecryptUpdate(ctx, plaintext.data(), &len, (unsigned char*)ciphertext.data(), (int)ciphertext.size());
plaintext_len = len;
if (EVP_DecryptFinal_ex(ctx, plaintext.data() + len, &len) <= 0) {
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Decryption failed. Wrong key or corrupted data.");
}
plaintext_len += len;
EVP_CIPHER_CTX_free(ctx);
return std::string((char*)plaintext.data(), plaintext_len);
}
};
// Pybind11 module definition
PYBIND11_MODULE(vault_core, m) {
m.doc() = "High-performance C++ Encryption Core for SecureVault";
py::class_<VaultEngine>(m, "VaultEngine")
.def(py::init<>())
.def("encrypt", &VaultEngine::encrypt, "Encrypt a string using AES-256-CBC")
.def("decrypt", &VaultEngine::decrypt, "Decrypt a string using AES-256-CBC");
}