Skip to content

Commit

Permalink
encryptWithAES and decryptWithAES methods have been added
Browse files Browse the repository at this point in the history
  • Loading branch information
leventkaragol committed May 18, 2024
1 parent 2e1d16e commit b976e05
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 27 deletions.
26 changes: 18 additions & 8 deletions examples/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,31 @@

using namespace lklibs;

void encrypt()
void encryptWithAES()
{
std::string input = "Hello, World!";
std::string key = "asdqwerty123asd1234safd324dfdsdf";
auto plainText = "This text will be encrypted soon";
auto key = "mySecretKey";

auto encrypted = CryptoService::encryptWithAES(input, key);
auto decrypted = CryptoService::decryptWithAES(encrypted, key);
auto encryptedText = CryptoService::encryptWithAES(plainText, key);

std::cout << "Encrypted: " << encrypted << std::endl;
std::cout << "Decrypted: " << decrypted << std::endl;
std::cout << "Encrypted Text: " << encryptedText << std::endl;
}

void decryptWithAES()
{
auto encryptedText = "D9ktQq1ZnV32JXr5YUpSJcTegqrfCHFi7aDNPGgrtsRmYLqS5YLGBKemqUwPzEeYLVN6ww4hL6ZptcZBLktbhg==";
auto key = "mySecretKey";

auto plainText = CryptoService::decryptWithAES(encryptedText, key);

std::cout << "Decrypted Text: " << plainText << std::endl;
}

int main()
{
encrypt();
encryptWithAES();

decryptWithAES();

return 0;
}
71 changes: 52 additions & 19 deletions src/libcpp-crypto.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,15 @@ SOFTWARE.
#define LIBCPP_CRYPTO_HPP

#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <string>
#include <vector>
#include <memory>
#include <array>
#include <random>
#include <iostream>
#include <stdexcept>
#include <iostream>

namespace lklibs
{
Expand All @@ -64,6 +62,7 @@ namespace lklibs
for (auto c : input)
{
char_array_3[i++] = c;

if (i == 3)
{
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
Expand All @@ -72,7 +71,9 @@ namespace lklibs
char_array_4[3] = char_array_3[2] & 0x3f;

for (i = 0; i < 4; i++)
{
ret += base64_chars[char_array_4[i]];
}

i = 0;
}
Expand All @@ -81,17 +82,23 @@ namespace lklibs
if (i)
{
for (int j = i; j < 3; j++)
{
char_array_3[j] = '\0';
}

char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);

for (int j = 0; j < i + 1; j++)
{
ret += base64_chars[char_array_4[j]];
}

while (i++ < 3)
{
ret += '=';
}
}

return ret;
Expand All @@ -105,27 +112,32 @@ namespace lklibs
"0123456789+/";

std::string ret;
int in_len = input.size();
int i = 0;
unsigned char char_array_4[4], char_array_3[3];

for (auto c : input)
{
if (c == '=' || !isBase64(c))
{
break;
}

char_array_4[i++] = c;
if (i == 4)
{
for (i = 0; i < 4; i++)
{
char_array_4[i] = base64_chars.find(char_array_4[i]);
}

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (i = 0; i < 3; i++)
{
ret += char_array_3[i];
}

i = 0;
}
Expand All @@ -134,17 +146,23 @@ namespace lklibs
if (i)
{
for (int j = i; j < 4; j++)
{
char_array_4[j] = 0;
}

for (int j = 0; j < 4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
for (unsigned char& j : char_array_4)
{
j = base64_chars.find(j);
}

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (int j = 0; j < i - 1; j++)
{
ret += char_array_3[j];
}
}

return ret;
Expand All @@ -162,17 +180,14 @@ namespace lklibs
public:
static std::string encryptWithAES(const std::string& plaintext, const std::string& key)
{
if (key.size() != 32) // AES-256 requires a 256-bit key
{
throw std::invalid_argument("Key length must be 256 bits (32 characters).");
}
std::string adjustedKey = adjustKeyLength(key);

std::vector<unsigned char> iv(AES_BLOCK_SIZE);
generateRandomIV(iv);

std::vector<unsigned char> ciphertext(plaintext.size() + AES_BLOCK_SIZE);

int ciphertext_len = encrypt(reinterpret_cast<const unsigned char*>(plaintext.c_str()), plaintext.length(), reinterpret_cast<const unsigned char*>(key.c_str()), iv.data(), ciphertext.data());
int ciphertext_len = encrypt(reinterpret_cast<const unsigned char*>(plaintext.c_str()), plaintext.length(), reinterpret_cast<const unsigned char*>(adjustedKey.c_str()), iv.data(), ciphertext.data());

ciphertext.resize(ciphertext_len);

Expand All @@ -182,10 +197,7 @@ namespace lklibs

static std::string decryptWithAES(const std::string& ciphertext, const std::string& key)
{
if (key.size() != 32) // AES-256 requires a 256-bit key
{
throw std::invalid_argument("Key length must be 256 bits (32 characters).");
}
std::string adjustedKey = adjustKeyLength(key);

auto encryptedText = Base64Converter::decode(ciphertext);

Expand All @@ -194,7 +206,7 @@ namespace lklibs

std::vector<unsigned char> plaintext(encryptedText.size() - AES_BLOCK_SIZE);

int plaintext_len = decrypt(reinterpret_cast<const unsigned char*>(encryptedText.data() + AES_BLOCK_SIZE), encryptedText.size() - AES_BLOCK_SIZE, reinterpret_cast<const unsigned char*>(key.c_str()), iv.data(), plaintext.data());
int plaintext_len = decrypt(reinterpret_cast<const unsigned char*>(encryptedText.data() + AES_BLOCK_SIZE), encryptedText.size() - AES_BLOCK_SIZE, reinterpret_cast<const unsigned char*>(adjustedKey.c_str()), iv.data(), plaintext.data());

if (plaintext_len == -1)
{
Expand All @@ -215,11 +227,14 @@ namespace lklibs
static void handleErrors()
{
unsigned long errCode;
while (errCode = ERR_get_error())

while ((errCode = ERR_get_error()))
{
char* err = ERR_error_string(errCode, NULL);
std::cerr << err << std::endl;
char errBuff[256];
ERR_error_string_n(errCode, errBuff, sizeof(errBuff));
std::cerr << errBuff << std::endl;
}

throw std::runtime_error("An OpenSSL error occurred");
}

Expand Down Expand Up @@ -299,6 +314,24 @@ namespace lklibs
handleErrors();
}
}

static std::string adjustKeyLength(const std::string& key)
{
if (key.size() == 32)
{
return key;
}
else if (key.size() > 32)
{
return key.substr(0, 32);
}
else
{
std::string adjusted_key = key;
adjusted_key.append(32 - key.size(), '0');
return adjusted_key;
}
}
};
}
#endif //LIBCPP_CRYPTO_HPP
21 changes: 21 additions & 0 deletions test/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "libcpp-crypto.hpp"
#include <gtest/gtest.h>

using namespace lklibs;

TEST(EncryptWithAESTest, EncryptionWithAESMustBeCompletedSuccessfullyWithAValidKey)
{
std::string plainText = "Test message to be used during tests";
std::string key = "mySecretKey";

auto encryptedText = CryptoService::encryptWithAES(plainText, key);

ASSERT_FALSE(encryptedText.empty()) << "encryptedText is empty";
}

int main(int argc, char** argv)
{
testing::InitGoogleTest(&argc, argv);

return RUN_ALL_TESTS();
}

0 comments on commit b976e05

Please sign in to comment.