-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from D7EAD/D7EAD-pmajor-1
HMAC implementation update
- Loading branch information
Showing
23 changed files
with
2,667 additions
and
397 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<h1>Keyed-Hash Message Authentication Codes (HMACs)</h1> | ||
<p>While they may sound considerably more complicated, HMACs aren't too different from cryptographic hashes at the end of the day. HMACs are keyed hashes of data meaning, simply, that an HMAC is used to generate a unique hash digest of data when that data is paired with another specific piece of data--a key.</p> | ||
|
||
<p>Take, for instance, the simple example hash function of <code>H(x) = y</code> where <code>H</code> is our hash function, <code>x</code> is our input data, and <code>y</code> is our output hash digest. The output digest depends on two things:</p> | ||
|
||
- The hash function in use. | ||
- The input supplied to said function. | ||
|
||
<p>Now, take, for instance, the following naive keyed hash algorithm *<code>H(x + k) = y</code> where <code>H</code> is our hash function, <code>x</code> is our input data, <code>k</code> is our key data, and <code>y</code> is our output hash digest. The output digest <b>now</b> depends on three things:</p> | ||
|
||
- The hash function in use. | ||
- The input supplied to said function. | ||
- The key data. | ||
|
||
<p>Hash functions provide collision-resistance whereas an HMAC provides both collision-resistance and <i>unforgeability</i>. Due to this provided element of unforgeability, HMACs are used in combination with hash algorithms to prove not only that data is unmodified, but that whoever calculated the hash for said data did so with the correct key--otherwise the incorrect HMAC would result.</p> | ||
|
||
<p>Simply put, a hash allows for <b>verification of the authenticity of data</b> whereas an HMAC allows for <b>verification of both the authenticity of data and the originator of said data</b>.</p> | ||
|
||
<p><i>*Keep in mind that HMACs do not simply operate as a hash function <code>H</code> applied on a key <code>k</code> appended to data <code>x</code>. How HMACs are calculated is a bit more nuanced. Hash algorithms are not HMACs and vice-versa--the HMAC mechanism works atop existing hash algorithms. You can read more about the RFC specification <a href="https://www.rfc-editor.org/rfc/rfc2104">here</a>.</i></p> | ||
|
||
<br> | ||
<h1>Using Hash++</h1> | ||
Hash++ offers a simple set of methods to generate one or multiple HMACs given data and an associated key. You can find the signatures for the functions below. | ||
|
||
``` | ||
static hashpp::hash getHMAC(hashpp::ALGORITHMS algorithm, const std::string& key, const std::string& data; | ||
static hashpp::hashCollection getHMACs(const HMAC_DataContainer& keyDataSet); | ||
static hashpp::hashCollection getHMACs(const std::vector<HMAC_DataContainer>& keyDataSets); | ||
static hashpp::hashCollection getHMACs(const std::initializer_list<HMAC_DataContainer>& keyDataSets); | ||
template <class... _Ts, ...> static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data); | ||
``` | ||
|
||
<br> | ||
You can easily generate an HMAC for a single piece of data using Hash++. See below for an example. | ||
https://github.com/D7EAD/HashPlusPlus/blob/0ac434933e4d54b584b810d863a9f1a4a4f5f7b4/documentation/HMACs/getHMAC/getHMAC_usage.cpp#L10-L29 | ||
|
||
<br> | ||
In order to generate several HMACs for several pieces of data, we can use a <code>Container</code> alias <code>HMAC_DataContainer</code> (if you have not read about the Container class used by Hash++, please see the documentation for <b>Hashing</b>). See below for an example. | ||
https://github.com/D7EAD/HashPlusPlus/blob/fc5edb76cd829794a3fb34c416df7431653044e0/documentation/HMACs/getHMACs/getHMACs_usage.cpp#L14-L42 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
Basic usage of Hash++ getHMAC method. | ||
This file shows basic usage of the above described method | ||
and its overloads, as well as how data can be extracted | ||
from its returned object. | ||
*/ | ||
|
||
#include "hashpp.h" | ||
|
||
using namespace hashpp; | ||
|
||
int main() { | ||
// data we want to get HMAC of | ||
std::string dataToHash = "Hello World!"; | ||
|
||
// key to use for HMAC | ||
std::string key = "secret"; | ||
|
||
// get HMAC of dataToHash using SHA-256 | ||
auto hmac = get::getHMAC(ALGORITHMS::SHA2_256, key, dataToHash); | ||
|
||
// print out the hash | ||
std::cout << "HMAC: " << hmac << std::endl; | ||
|
||
// output: | ||
// 6fa7b4dea28ee348df10f9bb595ad985ff150a4adfd6131cca677d9acee07dc6 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
Basic usage of Hash++ getHMACs method. | ||
This file shows basic usage of the above described method | ||
and its overloads, as well as how data can be extracted | ||
from its returned object. | ||
*/ | ||
|
||
#include "hashpp.h" | ||
|
||
using namespace hashpp; | ||
|
||
int main() { | ||
// create HMAC_DataContainer object | ||
// to store algorithm to use, key, | ||
// and data to HMAC | ||
HMAC_DataContainer hmac_container; | ||
|
||
// set algorithm to use | ||
hmac_container.setAlgorithm(ALGORITHMS::SHA2_256); | ||
|
||
// set key to use | ||
hmac_container.setKey("secretKey"); | ||
|
||
// set data to HMAC | ||
hmac_container.setData("dataToHMAC1", "dataToHMAC2", "dataToHMAC3"); | ||
|
||
// calculate the HMACs for all data in container | ||
// using key and algorithm specified | ||
hashCollection hmacs = get::getHMACs(hmac_container); | ||
|
||
// parse and print each HMAC | ||
for (auto& hmac : hmacs["SHA2-256"]) { | ||
std::cout << hmac << std::endl; | ||
} | ||
|
||
// output: | ||
// f0dfad2b51176704f8fff07e2c6063417b1d361465b4f9eaacf9b756037bb815 | ||
// bf912338f4c9d21eff351d085a26b9723eb0da6582039d18a003046c3ae3fbef | ||
// abba2bd3400c1b03322fac45539462241ca6ae14a81d58e1db017a9bcb3947b2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<h1>Documentation</h1> | ||
<b>Hash++</b> is a modern C++17 header-only library that provides developers simple means of retrieving cryptographic hashes and keyed-hashed message authentication codes (HMACs) from the algorithm(s) of their choice. The library was developed with the goal of appealing to one particular type of developer--one who does not want to use larger, heavier, or more confusing libraries with unnecessary features to simply hash data. | ||
<br><br> | ||
In the directories listed below, you can find explanations of concepts found within the implementations of the library and example usage of features found within <b~>Hash++</b>. | ||
|
||
- <a href="/hashing">Hashing Documentation</a> | ||
- Covers basic hashing concepts and how to generate them using the library. | ||
- <a href="/HMACs">HMAC Documentation</a> | ||
- Covers basic HMAC concepts and how to generate them using the library. | ||
- <a href="/file_hashing">File-hashing Documentation</a> | ||
- Covers how to hash files using the library. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<h1>Using Hash++ to Generate File Hashes</h1> | ||
Much like how hashes can be generated using generic data, Hash++ provides functions for developers to find hashes for files and files in nested directories. The signatures for the methods can be found below. | ||
|
||
``` | ||
static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path); | ||
static hashpp::hashCollection getFilesHashes(const FilePathsContainer& filePathSet); | ||
static hashpp::hashCollection getFilesHashes(const std::vector<FilePathsContainer>& filePathSets); | ||
static hashpp::hashCollection getFilesHashes(const std::initializer_list<FilePathsContainer>& filePathSets); | ||
``` | ||
|
||
<br> | ||
Some file hashing functions, much like some other components of the library, make use of their own <code>Container</code> alias <code>FilePathsContainer</code> (if you have not read about the <code>Container</code> class used by Hash++, please see the documentation for <b>Hashing</b>). You can find an example of a single file being hashed below. | ||
https://github.com/D7EAD/HashPlusPlus/blob/ba418167da59826cda2a18990a90cf332d75308e/documentation/file_hashing/getFileHash/getFileHash_usage.cpp#L10-L29 | ||
|
||
<br> | ||
If you're in the business of hashing multiple files at once, you can find an example of such a use below. | ||
https://github.com/D7EAD/HashPlusPlus/blob/c007af7d81bdf054a389314ad1d7bbb6d0757262/documentation/file_hashing/getFilesHashes/getFilesHashes_usage.cpp#L14-L35 |
29 changes: 29 additions & 0 deletions
29
documentation/file_hashing/getFileHash/getFileHash_usage.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
Basic usage of Hash++ getFileHash method. | ||
This file shows basic usage of the above described method | ||
and its overloads, as well as how data can be extracted | ||
from its returned object. | ||
*/ | ||
|
||
#include "hashpp.h" | ||
|
||
using namespace hashpp; | ||
|
||
int main() { | ||
// path to file we want to hash (test.txt) | ||
std::string pathToFile = "N:/source/test.txt"; | ||
|
||
// store the resulting hash object of the file using SHA-256 | ||
auto hash = get::getFileHash(ALGORITHMS::SHA2_256, pathToFile); | ||
|
||
// print the hash digest | ||
std::cout << hash << std::endl; | ||
|
||
// or we can be more specific... | ||
std::cout << hash.getString() << std::endl; | ||
|
||
// output: | ||
// 4de0d727216e14760010efdb0cccf577853d7da4e122a507b422148940f4aa34 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
A hash a day keeps the doctor away. |
35 changes: 35 additions & 0 deletions
35
documentation/file_hashing/getFilesHashes/getFilesHashes_usage.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
Basic usage of Hash++ getFileHashes method. | ||
This file shows basic usage of the above described method | ||
and its overloads, as well as how data can be extracted | ||
from its returned object. | ||
*/ | ||
|
||
#include "hashpp.h" | ||
|
||
using namespace hashpp; | ||
|
||
int main() { | ||
// create a FilePathsContainer object | ||
FilePathsContainer path_cont1; | ||
|
||
// set its algorithm and some paths | ||
path_cont1.setAlgorithm(ALGORITHMS::SHA2_256); | ||
path_cont1.setData("N:/source/test.txt", "N:/source/test2.txt", "N:/source/test3.txt"); | ||
|
||
// get the hashes of each file via get::getFilesHashes | ||
// and store them in a hashCollection object | ||
hashCollection hashes = get::getFilesHashes(path_cont1); | ||
|
||
// parse and print the hashes | ||
for (auto& hash : hashes["SHA2-256"]) { | ||
std::cout << hash << std::endl; | ||
} | ||
|
||
// output: | ||
// 4de0d727216e14760010efdb0cccf577853d7da4e122a507b422148940f4aa34 | ||
// 7c88d6bc28e9bd6660b96cfa3b69cdbaaaf0187047267106842841357ac03bd8 | ||
// 44d25e664ce6d6e82beb7a14fe312d7c09c5dc107668a6d40449bc24938e5c73 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
A hash a day keeps the doctor away. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Too many hashes may lead to gastrointestinal issues. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Passwords should not be stored in plaintext. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<h1>Hashing</h1> | ||
Hashing, in simple terms, is the cryptographic process of assigning a unique fingerprint to data such that no other data will produce the same fingerprint as another piece of data. | ||
<br><br> | ||
In mathematical terms, hashing is the functional process of mapping any arbitrary data <code>X</code> to a fixed-size, unique, and seemingly nonsensical value <code>D</code>. Hashing algorithms are one-way functions such that, given an input <code>x</code> to some hash function <code>H</code>, it is facile to compute the output hash digest <code>D</code>; however, given only some hash function <code>H</code> and an associated output digest <code>D</code>, it is infeasible to compute the original input data <code>x</code>. | ||
<br><br> | ||
Simply, a one-way function <code>H(x) = D</code> is one such function that satisfies all constraints such that... | ||
|
||
- <code>D</code> is easily computed given <code>x</code>. | ||
- <code>H</code>'s output range is known. | ||
- Given only output <code>D</code> and function <code>H</code>, <code>x</code> is infeasibly computed such that <code>H(x) = D</code>. | ||
|
||
Given this inherent infeasibility of recovering initial input data to a given hash function, they are useful for a number of security purposes such as: | ||
|
||
- Message and file integrity verification. | ||
- Password verification. | ||
- Signature/identifier generation and verification. | ||
- Key Derivation Functions (KDFs). | ||
- Proof-of-Work. | ||
- Blockchain Technology. | ||
- Public-Key Cryptography. | ||
- CSPRNGs. | ||
|
||
<h1>Using Hash++</h1> | ||
Hash++ offers a simple set of methods to take advantage of the cryptographic-magic described above. You can generate simple hashes using the functions described below. | ||
|
||
``` | ||
static hashpp::hash getHash(hashpp::ALGORITHMS algorithm, const std::string& data); | ||
static hashpp::hashCollection getHashes(const DataContainer& dataSet) | ||
static hashpp::hashCollection getHashes(const std::vector<DataContainer>& dataSets); | ||
static hashpp::hashCollection getHashes(const std::initializer_list<DataContainer>& dataSets); | ||
template <class... _Ts, ...> static hashpp::hashCollection getHashes(hashpp::ALGORITHMS algorithm, const _Ts&... data); | ||
``` | ||
<br> | ||
Some function overloads found in Hash++ make use of a container class <code>Container</code> with aliases <code>DataContainer</code>, <code>HMAC_DataContainer</code>, and <code>FilePathsContainer</code>. This class allows developers to contain all data associated with a particular hash algorithm in one name, making it easier to pass several of them, if desired, and, in turn, several sets of data to hash. You can find the detailed implementation of the class below. | ||
https://github.com/D7EAD/HashPlusPlus/blob/8bf4d2971f5fab4ad0df75ea6f71a012841c504e/documentation/hashing/container/container.cpp#L1-L100 | ||
|
||
<br> | ||
While the class may seem daunting at first, below you can find examples of its use and instantiation, as well as how it can be passed to certain function overloads. | ||
https://github.com/D7EAD/HashPlusPlus/blob/8bf4d2971f5fab4ad0df75ea6f71a012841c504e/documentation/hashing/container/container_use.cpp#L14-L37 | ||
|
||
<br> | ||
As you can see above, when given a properly created <code>Container</code>, the library function <code>getHashes(...)</code> can easily calculate and retrieve the hash digests of the passed data contained in the container(s). The function <code>getHashes(...)</code> itself, though, returns a <code>hashCollection</code> object. This object can be parsed quite easily: | ||
https://github.com/D7EAD/HashPlusPlus/blob/b7fbc10fc627ab21c39a51698882641e1073c78e/documentation/hashing/getHashes/getHashes_usage.cpp#L14-L29 | ||
|
||
<br> | ||
Parsing <code>hashCollection</code> objects is great and all when you want to get the hashes of several pieces of data. However, what if you want to get the hash of a single piece of data? To do this, we make use of the library function <code>getHash</code> which returns a <code>hash</code> object. | ||
https://github.com/D7EAD/HashPlusPlus/blob/ffca4d776939f950dbce37d3477bd3e164cc7ba9/documentation/hashing/getHash/getHash_usage.cpp#L14-L26 |
Oops, something went wrong.