From fdcdc1054b612990a1d3bd55bee9233a90b21255 Mon Sep 17 00:00:00 2001 From: Nikola Petrov Date: Sun, 13 Aug 2023 01:28:01 +0200 Subject: [PATCH] Cryptography WIP --- Password_manager/Password_manager.vcxproj | 7 +- .../Password_manager.vcxproj.filters | 13 +- Password_manager/include/Buffer.h | 25 ++++ Password_manager/include/clipboard.hpp | 3 - Password_manager/include/cryptography.h | 23 ++++ Password_manager/include/win.h | 4 + Password_manager/source/cryptography.cpp | 127 ++++++++++++++++++ Password_manager/source/main.cpp | 3 +- .../source/{clipboard.cpp => win.cpp} | 32 ++++- 9 files changed, 227 insertions(+), 10 deletions(-) create mode 100644 Password_manager/include/Buffer.h delete mode 100644 Password_manager/include/clipboard.hpp create mode 100644 Password_manager/include/cryptography.h create mode 100644 Password_manager/include/win.h create mode 100644 Password_manager/source/cryptography.cpp rename Password_manager/source/{clipboard.cpp => win.cpp} (64%) diff --git a/Password_manager/Password_manager.vcxproj b/Password_manager/Password_manager.vcxproj index db9a7df..3662ed7 100644 --- a/Password_manager/Password_manager.vcxproj +++ b/Password_manager/Password_manager.vcxproj @@ -133,11 +133,14 @@ - + + - + + + diff --git a/Password_manager/Password_manager.vcxproj.filters b/Password_manager/Password_manager.vcxproj.filters index 93d5eb2..2c16131 100644 --- a/Password_manager/Password_manager.vcxproj.filters +++ b/Password_manager/Password_manager.vcxproj.filters @@ -18,12 +18,21 @@ Source Files - + + Source Files + + Source Files - + + Header Files + + + Header Files + + Header Files diff --git a/Password_manager/include/Buffer.h b/Password_manager/include/Buffer.h new file mode 100644 index 0000000..26affbe --- /dev/null +++ b/Password_manager/include/Buffer.h @@ -0,0 +1,25 @@ +#pragma once + + +class Buffer +{ +public: + unsigned char* buffer = nullptr; + size_t size = 0; + Buffer(size_t size) + { + this->size = size; + this->buffer = new unsigned char[size]; + } + + Buffer() { + size = 0; + buffer = nullptr; + } + + ~Buffer() + { + if (buffer) delete[] buffer; + } + +}; \ No newline at end of file diff --git a/Password_manager/include/clipboard.hpp b/Password_manager/include/clipboard.hpp deleted file mode 100644 index f830774..0000000 --- a/Password_manager/include/clipboard.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -bool put_data_on_clipboard(const char* text); \ No newline at end of file diff --git a/Password_manager/include/cryptography.h b/Password_manager/include/cryptography.h new file mode 100644 index 0000000..2eec060 --- /dev/null +++ b/Password_manager/include/cryptography.h @@ -0,0 +1,23 @@ +#pragma once +#include + +struct evp_cipher_ctx_st; +typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; + + +class Cryptography +{ +public: + Cryptography(const char* password); + ~Cryptography(); + int encrypt(uint8_t* input_buffer, int32_t input_buffer_size); + int decrypt(uint8_t* input_buffer); + +private: + uint8_t key[32] = { 0 }; + uint8_t iv[16] = { 0 }; + EVP_CIPHER_CTX* ctx = nullptr; + + bool generate_key_and_iv_from_password(const char* password); + void handleErrors(); +}; diff --git a/Password_manager/include/win.h b/Password_manager/include/win.h new file mode 100644 index 0000000..f02eccf --- /dev/null +++ b/Password_manager/include/win.h @@ -0,0 +1,4 @@ +#pragma once + +bool put_data_on_clipboard(const char* text); +std::string get_passwd(); \ No newline at end of file diff --git a/Password_manager/source/cryptography.cpp b/Password_manager/source/cryptography.cpp new file mode 100644 index 0000000..97f7ffa --- /dev/null +++ b/Password_manager/source/cryptography.cpp @@ -0,0 +1,127 @@ +#include +#include +#include +#include +#include + +#include "cryptography.h" +#include "buffer.h" + +Cryptography::Cryptography(const char* password) +{ + OpenSSL_add_all_algorithms(); + ERR_load_crypto_strings(); + + if (!generate_key_and_iv_from_password(password)) + { + std::cout << "Error generating key and IV from password\n"; + return; + } +} + +Cryptography::~Cryptography() +{ + ERR_free_strings(); + EVP_cleanup(); +} + +int Cryptography::encrypt(uint8_t* input_buffer, int32_t input_buffer_size) +{ + // Allocate memory for the ciphertext + int ciphertext_len = 0; + + Buffer encrypted_buffer(input_buffer_size + EVP_CIPHER_block_size(EVP_aes_256_cbc())); + + // Create and initialize the context for encryption + ctx = EVP_CIPHER_CTX_new(); + if (!ctx) handleErrors(); + + if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) handleErrors(); + + // Perform encryption + if (1 != EVP_EncryptUpdate(ctx, encrypted_buffer.buffer, &ciphertext_len, input_buffer, input_buffer_size)) handleErrors(); + + int final_len; + if (1 != EVP_EncryptFinal_ex(ctx, encrypted_buffer.buffer + ciphertext_len, &final_len)) handleErrors(); + ciphertext_len += final_len; + + // Clean up the context + EVP_CIPHER_CTX_free(ctx); + + + // store the encrypted buffer to file + + std::ofstream file("encrypted_file.bin", std::ios::binary); + if (file) + { + file.write((char*)encrypted_buffer.buffer, ciphertext_len); + file.close(); + } + + + + return ciphertext_len; +} + +int Cryptography::decrypt(uint8_t* out_buffer) +{ + // read the encrypted buffer from file + + + + std::ifstream file("encrypted_file.bin", std::ios::binary); + if (!file) return 0; + + file.seekg(0, std::ios::end); + int encrypted_buffer_len = file.tellg(); + file.seekg(0, std::ios::beg); + + Buffer encrypted_buffer(encrypted_buffer_len); + + file.read((char*)encrypted_buffer.buffer, encrypted_buffer_len); + file.close(); + + + + + + + + ctx = EVP_CIPHER_CTX_new(); + if (!ctx) handleErrors(); + + if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) handleErrors(); + + int decrypted_len = 0; + if (1 != EVP_DecryptUpdate(ctx, out_buffer, &decrypted_len, encrypted_buffer.buffer, encrypted_buffer_len)) handleErrors(); + int final_len; + if (1 != EVP_DecryptFinal_ex(ctx, out_buffer + decrypted_len, &final_len)) handleErrors(); + decrypted_len += final_len; + + // Clean up the context + EVP_CIPHER_CTX_free(ctx); + + return decrypted_len; +} + +bool Cryptography::generate_key_and_iv_from_password(const char* password) +{ + int iterations = 10000; + + // Derive key and IV using PBKDF2 + if (1 != PKCS5_PBKDF2_HMAC(password, strlen(password), nullptr, 0, iterations, EVP_sha256(), 32, key)) return false; + if (1 != PKCS5_PBKDF2_HMAC(password, strlen(password), nullptr, 0, iterations, EVP_sha256(), 16, iv)) return false; + return true; +} + +void Cryptography::handleErrors() +{ + EVP_CIPHER_CTX_free(ctx); + + while (auto error = ERR_get_error()) + { + char* error_string = ERR_error_string(error, nullptr); + std::cout << error_string << "\n"; + } + abort(); +} \ No newline at end of file diff --git a/Password_manager/source/main.cpp b/Password_manager/source/main.cpp index f51b44d..1b230a7 100644 --- a/Password_manager/source/main.cpp +++ b/Password_manager/source/main.cpp @@ -1,7 +1,6 @@ #include #include - -#include "clipboard.hpp" +#include "win.h" struct Pass { diff --git a/Password_manager/source/clipboard.cpp b/Password_manager/source/win.cpp similarity index 64% rename from Password_manager/source/clipboard.cpp rename to Password_manager/source/win.cpp index f110c98..918ce10 100644 --- a/Password_manager/source/clipboard.cpp +++ b/Password_manager/source/win.cpp @@ -1,6 +1,7 @@ #include #include -#include "clipboard.hpp" +#include +#include "win.h" bool put_data_on_clipboard(const char* text) { int len = strlen(text); @@ -35,4 +36,33 @@ bool put_data_on_clipboard(const char* text) { // Clean up and close the clipboard CloseClipboard(); return true; +} + + +std::string get_passwd() +{ + + HANDLE hStdInput = GetStdHandle(STD_INPUT_HANDLE); + DWORD mode = 0; + + // Create a restore point Mode + // is know 503 + GetConsoleMode(hStdInput, &mode); + + // Enable echo input + // set to 499 + SetConsoleMode( hStdInput, mode & (~ENABLE_ECHO_INPUT)); + + // Take input + std::string ipt; + std::getline(std::cin, ipt); + + // Otherwise next cout will print + // into the same line + std::cout << std::endl; + + // Restore the mode + SetConsoleMode(hStdInput, mode); + + return ipt; } \ No newline at end of file