diff --git a/README.md b/README.md index 3a6ebfa..1a50e37 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Easy-to-use, symmetric (AES-256) and asymmetric (RSA) encryption and also hash ( * [How to add it to my project](#how-to-add-it-to-my-project) * [How to use? (Symmetric Encryption with AES)](#how-to-use-symmetric-encryption-with-aes) * [How to use? (Hash with SHA-256)](#how-to-use-hash-with-sha-256) +* [How to use? (Hash with HMAC SHA-256)](#how-to-use-hash-with-hmac-sha-256) * [How to use? (Asymmetric Encryption with RSA)](#how-to-use-asymmetric-encryption-with-rsa) * [How do I generate Public/Private Keys?](#how-do-i-generate-publicprivate-keys) * [Relationship between key size and max text length that can be encrypted](#relationship-between-key-size-and-max-text-length-that-can-be-encrypted) @@ -102,6 +103,29 @@ int main() { } ``` +## How to use? (Hash with HMAC SHA-256) + +All you need to do is call the **"hashWithHMACSHA256"** function to hash the given text by given secret key with HMAC SHA-256. + +```cpp +#include "libcpp-crypto.hpp" + +using namespace lklibs; + +int main() { + + auto plainText = "This text will be hashed soon"; + + const auto key = "mySecretKey"; + + const auto hashedText = CryptoService::hashWithHMACSHA256(plainText, key); + + std::cout << "Hash: " << hashedText << std::endl; + + return 0; +} +``` + ## How to use? (Asymmetric Encryption with RSA) To encrypt and decrypt the given text with RSA, all you need to do is call the **"encryptWithRSA"** and diff --git a/examples/main.cpp b/examples/main.cpp index 74d9773..125ee69 100644 --- a/examples/main.cpp +++ b/examples/main.cpp @@ -252,6 +252,16 @@ void hash() std::cout << "Hash: " << hashText << std::endl; } +void hashWithHMACSHA256() +{ + const auto plainText = "This text will be hashed soon"; + const auto key = "mySecretKey"; + + const auto hashText = CryptoService::hashWithHMACSHA256(plainText, key); + + std::cout << "Hash: " << hashText << std::endl; +} + int main() { // Symmetric Encryption with AES @@ -290,5 +300,7 @@ int main() hash(); + hashWithHMACSHA256(); + return 0; } diff --git a/src/libcpp-crypto.hpp b/src/libcpp-crypto.hpp index b57bf3b..2c08b1d 100644 --- a/src/libcpp-crypto.hpp +++ b/src/libcpp-crypto.hpp @@ -36,6 +36,7 @@ SOFTWARE. #include #include #include +#include #include #include #include @@ -735,6 +736,43 @@ namespace lklibs return ""; } + + /** + * @brief Hashes the given string with HMAC SHA-256 + * + * @param plainText String to hash + * @param key key to use for hashing plainText + * + * @return Hashed string + */ + inline std::string hashWithHMACSHA256(const std::string& plainText, const std::string& key) + { + const auto keyBytes = reinterpret_cast(key.c_str()); + const size_t keyLength = key.length(); + + const auto data = reinterpret_cast(plainText.c_str()); + const size_t dataLength = plainText.length(); + + unsigned char result[SHA256_DIGEST_LENGTH]; + unsigned int resultLength; + + if (HMAC(EVP_sha256(), keyBytes, static_cast(keyLength), data, static_cast(dataLength), result, &resultLength) == nullptr) + { + std::cerr << "Error: HMAC calculation failed." << std::endl; + + return ""; + } + + const std::vector hashBytes(result, result + resultLength); + + std::stringstream ss; + for (const unsigned char byte : hashBytes) + { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); + } + + return ss.str(); + } } } diff --git a/test/test.cpp b/test/test.cpp index 05c02cf..c2d6149 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -494,6 +494,16 @@ TEST(HashTest, HashWithSHA256MustBeCompletedSuccessfully) ASSERT_EQ(hashText, "d32448bab2777b376a5592e384146c3c0182ba589e2521bd0275f2cef6a50546") << "Hash is invalid"; } +TEST(HmacSha256Test, HashWithHMACSHA256MustBeCompletedSuccessfully) +{ + const auto plainText = "This text will be hashed soon"; + const auto key = "mySecretKey"; + + const auto hashText = CryptoService::hashWithHMACSHA256(plainText, key); + + ASSERT_EQ(hashText, "875dae56af4cb9c9c1b2e7f30e28704da4f1933bf85bb180409761f9c4721186") << "Hash is invalid"; +} + int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv);