@@ -32,7 +32,7 @@ void Decryption::decryptFile() {
32
32
" dummykey\n "
33
33
" -----END RSA PRIVATE KEY-----\n " ); // Replace with your private key string
34
34
#endif
35
- RSA* privateKey = loadPrivateKey (privateKeyString);
35
+ EVP_PKEY * privateKey = loadPrivateKey (privateKeyString);
36
36
if (!privateKey) {
37
37
return ;
38
38
}
@@ -42,31 +42,27 @@ void Decryption::decryptFile() {
42
42
pugi::xml_parse_result result = encryptedDocLoaded.load_file (encryptedFile_.c_str ());
43
43
if (!result) {
44
44
std::cerr << " XML parse error: " << result.description () << std::endl;
45
- RSA_free (privateKey);
45
+ EVP_PKEY_free (privateKey);
46
46
return ;
47
47
}
48
48
49
49
pugi::xml_node root = encryptedDocLoaded.child (" EncryptedData" );
50
50
std::string base64EncryptedSessionKeyLoaded = root.child_value (" SessionKey" );
51
51
std::string base64EncryptedLoaded = root.child_value (" Data" );
52
52
53
- // Base64 decode encrypted session key and data
54
- std::string encryptedSessionKeyLoaded = base64_decode (base64EncryptedSessionKeyLoaded);
55
- std::string encryptedLoaded = base64_decode (base64EncryptedLoaded);
56
-
57
53
// Decrypt session key
58
- std::string decryptedSessionKey = decryptSessionKey (encryptedSessionKeyLoaded , privateKey);
54
+ std::string decryptedSessionKey = decryptSessionKey (base64EncryptedSessionKeyLoaded , privateKey);
59
55
60
56
// Decrypt XML string
61
- std::string decrypted = decrypt (encryptedLoaded, privateKey );
57
+ std::string decrypted = decryptData (base64EncryptedLoaded, reinterpret_cast < const unsigned char *>(decryptedSessionKey. c_str ()) );
62
58
63
59
// Write the decrypted data to a file
64
60
// std::ofstream decryptedFile("decrypted.xml");
65
61
// decryptedFile << decrypted;
66
62
// decryptedFile.close();
67
63
68
64
decryptedContent_ = decrypted;
69
- RSA_free (privateKey);
65
+ EVP_PKEY_free (privateKey);
70
66
}
71
67
72
68
/* *
@@ -79,107 +75,147 @@ std::string Decryption::getDecryptedContent() const {
79
75
}
80
76
81
77
/* *
82
- * @brief Decrypts the given ciphertext using the provided RSA key .
78
+ * @brief Loads the private key from the given PEM string .
83
79
*
84
- * @param ciphertext The ciphertext to decrypt.
85
- * @param key The RSA key for decryption.
86
- * @return The decrypted plaintext.
80
+ * @param privateKeyString The PEM string representing the private key.
81
+ * @return The loaded EVP private key.
87
82
*/
88
- std::string Decryption::decrypt (const std::string& ciphertext, RSA* key) {
89
- int rsaLen = RSA_size (key);
90
- int len = ciphertext.size ();
91
- std::string plaintext;
92
-
93
- for (int i = 0 ; i < len; i += rsaLen) {
94
- std::vector<unsigned char > buffer (rsaLen);
95
- std::string substr = ciphertext.substr (i, rsaLen);
96
-
97
- int result = RSA_private_decrypt (substr.size (), reinterpret_cast <const unsigned char *>(substr.data ()), buffer.data (), key, RSA_PKCS1_OAEP_PADDING);
98
- if (result == -1 ) {
99
- std::cerr << " Decryption error: " << ERR_error_string (ERR_get_error (), NULL ) << std::endl;
100
- return " " ;
101
- }
102
-
103
- plaintext.append (reinterpret_cast <char *>(buffer.data ()), result);
83
+ EVP_PKEY *Decryption::loadPrivateKey (const std::string& privateKeyString) {
84
+ EVP_PKEY *pkey = nullptr ;
85
+ BIO* privateKeyBio = BIO_new_mem_buf (privateKeyString.data (), privateKeyString.size ());
86
+
87
+ if (!privateKeyBio) {
88
+ std::cerr << " Error creating BIO for private key" << std::endl;
89
+ return nullptr ;
90
+ }
91
+
92
+ char * passphrase_cstr = const_cast <char *>(passphrase.c_str ());
93
+ if (!PEM_read_bio_PrivateKey (privateKeyBio, &pkey, NULL , passphrase_cstr)) {
94
+ std::cerr << " Error reading private key" << std::endl;
95
+ BIO_free (privateKeyBio);
96
+ return nullptr ;
104
97
}
105
98
106
- return plaintext;
99
+ BIO_free (privateKeyBio);
100
+ return pkey;
107
101
}
108
102
109
103
/* *
110
- * @brief Decodes the given base64-encoded string.
104
+ * @brief
111
105
*
112
- * @param input The base64-encoded input string.
113
- * @return The decoded output string .
106
+ * @param encoded The base64-encoded input string.
107
+ * @return std::vector<unsigned char> The decoded dynamic array of characters .
114
108
*/
115
- std::string Decryption::base64_decode (const std::string& input) {
109
+ std::vector<unsigned char > Decryption::base64Decode (const std::string& encoded) {
110
+ BIO* bio = BIO_new_mem_buf (encoded.data (), -1 );
116
111
BIO* b64 = BIO_new (BIO_f_base64 ());
117
112
BIO_set_flags (b64, BIO_FLAGS_BASE64_NO_NL);
113
+ bio = BIO_push (b64, bio);
118
114
119
- BIO* bmem = BIO_new_mem_buf (input.data (), input.size ());
120
- b64 = BIO_push (b64, bmem);
121
-
122
- std::string output;
123
- output.resize (input.size ());
124
-
125
- int decoded_size = BIO_read (b64, &output[0 ], input.size ());
126
- output.resize (decoded_size);
127
- BIO_free_all (b64);
115
+ std::vector<unsigned char > decoded (encoded.length ());
116
+ int decodedLen = BIO_read (bio, decoded.data (), encoded.length ());
117
+ decoded.resize (decodedLen);
128
118
129
- return output;
119
+ BIO_free_all (bio);
120
+ return decoded;
130
121
}
131
122
132
123
/* *
133
- * @brief Loads the private key from the given PEM string .
124
+ * @brief Decrypts the given encrypted session key using the provided EVP key .
134
125
*
135
- * @param privateKeyString The PEM string representing the private key.
136
- * @return The loaded RSA private key.
126
+ * @param encryptedSessionKey The encrypted session key.
127
+ * @param privateKey The EVP key for decryption.
128
+ * @return The decrypted session key.
137
129
*/
138
- RSA* Decryption::loadPrivateKey (const std::string& privateKeyString) {
139
- RSA* key = nullptr ;
140
- BIO* privateKeyBio = BIO_new_mem_buf (privateKeyString.data (), privateKeyString.size ());
130
+ std::string Decryption::decryptSessionKey (const std::string& encryptedSessionKey, EVP_PKEY* privateKey) {
131
+ std::vector<unsigned char > decodedKey = base64Decode (encryptedSessionKey);
141
132
142
- if (!privateKeyBio) {
143
- std::cerr << " Error creating BIO for private key" << std::endl;
144
- return nullptr ;
133
+ EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new (privateKey, NULL );
134
+ if (!ctx) {
135
+ std::cerr << " Failed to create EVP_PKEY_CTX" << std::endl;
136
+ return " " ;
145
137
}
146
138
147
- if (! PEM_read_bio_RSAPrivateKey (privateKeyBio, &key, NULL , ( void *)passphrase. c_str ()) ) {
148
- std::cerr << " Error reading private key " << std::endl;
149
- BIO_free (privateKeyBio );
150
- return nullptr ;
139
+ if (EVP_PKEY_decrypt_init (ctx) <= 0 ) {
140
+ std::cerr << " EVP_PKEY_decrypt_init failed " << std::endl;
141
+ EVP_PKEY_CTX_free (ctx );
142
+ return " " ;
151
143
}
152
144
153
- BIO_free (privateKeyBio);
154
- return key;
145
+ if (EVP_PKEY_CTX_set_rsa_padding (ctx, RSA_PKCS1_OAEP_PADDING) <= 0 ) {
146
+ std::cerr << " EVP_PKEY_CTX_set_rsa_padding failed" << std::endl;
147
+ EVP_PKEY_CTX_free (ctx);
148
+ return " " ;
149
+ }
150
+
151
+ size_t outLen;
152
+ if (EVP_PKEY_decrypt (ctx, NULL , &outLen, decodedKey.data (), decodedKey.size ()) <= 0 ) {
153
+ std::cerr << " EVP_PKEY_decrypt (determine length) failed" << std::endl;
154
+ EVP_PKEY_CTX_free (ctx);
155
+ return " " ;
156
+ }
157
+
158
+ std::vector<unsigned char > out (outLen);
159
+ if (EVP_PKEY_decrypt (ctx, out.data (), &outLen, decodedKey.data (), decodedKey.size ()) <= 0 ) {
160
+ std::cerr << " EVP_PKEY_decrypt failed" << std::endl;
161
+ EVP_PKEY_CTX_free (ctx);
162
+ return " " ;
163
+ }
164
+
165
+ EVP_PKEY_CTX_free (ctx);
166
+
167
+ return std::string (out.begin (), out.begin () + outLen);
155
168
}
156
169
157
170
/* *
158
- * @brief Decrypts the given encrypted session key using the provided RSA key.
171
+ * @brief
159
172
*
160
- * @param encryptedSessionKey The encrypted session key .
161
- * @param key The RSA key for decryption.
162
- * @return The decrypted session key .
173
+ * @param encryptedData The encrypted data to decrypt .
174
+ * @param sessionKey The session key for data decryption.
175
+ * @return std::string The decrypted plaintext .
163
176
*/
164
- std::string Decryption::decryptSessionKey (const std::string& encryptedSessionKey, RSA* key) {
165
- std::vector<unsigned char > decryptedSessionKey (RSA_size (key));
166
- if (RSA_private_decrypt (encryptedSessionKey.size (), reinterpret_cast <const unsigned char *>(encryptedSessionKey.data ()), decryptedSessionKey.data (), key, RSA_PKCS1_OAEP_PADDING) == -1 ) {
167
- std::cerr << " Session key decryption error: " << ERR_error_string (ERR_get_error (), NULL ) << std::endl;
177
+ std::string Decryption::decryptData (const std::string& encryptedData, const unsigned char * sessionKey) {
178
+ std::vector<unsigned char > decodedData = base64Decode (encryptedData);
179
+
180
+ // Extract the IV from the decoded data
181
+ unsigned char iv[EVP_MAX_IV_LENGTH];
182
+ int iv_len = EVP_CIPHER_iv_length (EVP_aes_128_cbc ());
183
+ std::copy (decodedData.begin (), decodedData.begin () + iv_len, iv);
184
+ const unsigned char * ciphertext = decodedData.data () + iv_len;
185
+ size_t ciphertextLen = decodedData.size () - iv_len;
186
+
187
+ EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new ();
188
+ if (!ctx) {
189
+ std::cerr << " Failed to create EVP_CIPHER_CTX" << std::endl;
168
190
return " " ;
169
191
}
170
192
171
- return std::string (reinterpret_cast <char *>(decryptedSessionKey.data ()), decryptedSessionKey.size ());
172
- }
193
+ if (EVP_DecryptInit_ex (ctx, EVP_aes_128_cbc (), NULL , sessionKey, iv) != 1 ) {
194
+ std::cerr << " EVP_DecryptInit_ex failed" << std::endl;
195
+ EVP_CIPHER_CTX_free (ctx);
196
+ return " " ;
197
+ }
198
+
199
+ std::vector<unsigned char > plaintext (ciphertextLen + EVP_CIPHER_block_size (EVP_aes_128_cbc ()));
200
+ int len = 0 ;
201
+ int plaintextLen = 0 ;
173
202
174
- // int main(int argc, char* argv[]) {
175
- // if (argc < 2) {
176
- // std::cerr << "Usage: " << argv[0] << " <encrypted file> <public key>\n";
177
- // return -1;
178
- // }
203
+ if (EVP_DecryptUpdate (ctx, plaintext.data (), &len, ciphertext, ciphertextLen) != 1 ) {
204
+ std::cerr << " EVP_DecryptUpdate failed" << std::endl;
205
+ EVP_CIPHER_CTX_free (ctx);
206
+ return " " ;
207
+ }
208
+ plaintextLen += len;
179
209
180
- // std::string encryptedFile = argv[1];
210
+ if (EVP_DecryptFinal_ex (ctx, plaintext.data () + plaintextLen, &len) != 1 ) {
211
+ std::cerr << " EVP_DecryptFinal_ex failed" << std::endl;
212
+ EVP_CIPHER_CTX_free (ctx);
213
+ return " " ;
214
+ }
215
+ plaintextLen += len;
216
+ plaintext.resize (plaintextLen);
181
217
182
- // Decryption decryption(encryptedFile );
218
+ EVP_CIPHER_CTX_free (ctx );
183
219
184
- // return 0 ;
185
- // }
220
+ return std::string (plaintext. begin (), plaintext. end ()) ;
221
+ }
0 commit comments