Skip to content

Commit 239ca5e

Browse files
authored
Merge pull request #10 from D7EAD/D7EAD-pmajor-1
HMAC implementation update
2 parents aa531e5 + c3b4525 commit 239ca5e

File tree

23 files changed

+2667
-397
lines changed

23 files changed

+2667
-397
lines changed

README.md

Lines changed: 14 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,19 @@
66
Hash++ is a C++17 header-only library that allows a user to retrieve multiple types of hashes from data, files, and files in nested directories. The original purpose behind this library was to create a header-file only implementation of multiple different hash algorithms. You can find a list of the <i>currently</i> supported hash algorithms below.
77
<br>
88
<h1><i>Supported Algorithms</i></h1>
9-
<ul>
10-
<li>MD5</li>
11-
<li>MD4</li>
12-
<li>MD2</li>
13-
<li>SHA-1</li>
14-
<li>SHA2-224</li>
15-
<li>SHA2-256</li>
16-
<li>SHA2-384</li>
17-
<li>SHA2-512</li>
18-
<li>SHA2-512/224</li>
19-
<li>SHA2-512/256</li>
20-
</ul>
9+
10+
| Algorithm | HMAC Support? |
11+
| :-------------: | :-----------------: |
12+
| MD5 | :heavy_check_mark: |
13+
| MD4 | :heavy_check_mark: |
14+
| MD2 | :heavy_check_mark: |
15+
| SHA1 | :heavy_check_mark: |
16+
| SHA2-224 | :heavy_check_mark: |
17+
| SHA2-256 | :heavy_check_mark: |
18+
| SHA2-384 | :heavy_check_mark: |
19+
| SHA2-512 | :heavy_check_mark: |
20+
| SHA2-512/224 | :heavy_check_mark: |
21+
| SHA2-512/256 | :heavy_check_mark: |
2122

2223
Hash++ also aims to be a suitable alternative to heavier, statically and dynamically-linked libraries such as OpenSSL and Crypto++. I created it keeping in mind the mindset of a programmer who simply wants a header-only file that lets them easily and comfortably <i>"just hash sh*t."</i> Does it really have to be that difficult?
2324

@@ -93,40 +94,4 @@ No, it doesn't.
9394
```
9495

9596
<h1><i>Using Hash++</i></h1>
96-
My original design idea behind Hash++ was for it to be <b>simple</b>. This has remained unchanged.
97-
<br><br>
98-
Below you can find the signatures of the <i>only</i> functions necessary to accomplish retrieving hashes from both single or multiple sets of data, files, and files in nested directories. All functions are located in the <code>hashpp</code> namespace under class <code>get</code> (<code>hashpp::get</code>).
99-
<br><br>
100-
You can find examples of Hash++ in use in the <a href="/examples">/examples</a> and <a href="/tests">/tests</a> directories.
101-
<br>
102-
<h3><code>getHash</code></h3>
103-
Retrieve a single hash from a single piece of data.
104-
105-
```cpp
106-
// function to return a resulting hash from selected ALGORITHM and passed data
107-
static hashpp::hash getHash(hashpp::ALGORITHMS algorithm, const std::string& data)
108-
```
109-
110-
<h3><code>getHashes</code></h3>
111-
Retrieve a collection of hashes from multiple pieces of data.
112-
113-
```cpp
114-
// function to return a collection of resulting hashes from selected ALGORITHMS and passed data
115-
static hashpp::hashCollection getHashes(const std::vector<std::pair<hashpp::ALGORITHMS, std::vector<std::string>>>& algorithmDataPairs)
116-
```
117-
118-
<h3><code>getFileHash</code></h3>
119-
Retrieve a single hash from a single file.
120-
121-
```cpp
122-
// function to return a resulting hash from selected ALGORITHM and passed file
123-
static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path)
124-
```
125-
126-
<h3><code>getFilesHashes</code></h3>
127-
Retrieve a collection of hashes from multiple files or files in nested directories.
128-
129-
```cpp
130-
// function to return a collection of resulting hashes from selected ALGORITHMS and passed files (with recursive directory support)
131-
static hashpp::hashCollection getFilesHashes(const std::vector<std::pair<hashpp::ALGORITHMS, std::vector<std::string>>>& algorithmPathPairs)
132-
```
97+
You can find detailed documentation in the <a href="/documentation">/documentation</a> directory.

documentation/HMACs/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<h1>Keyed-Hash Message Authentication Codes (HMACs)</h1>
2+
<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>
3+
4+
<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>
5+
6+
- The hash function in use.
7+
- The input supplied to said function.
8+
9+
<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>
10+
11+
- The hash function in use.
12+
- The input supplied to said function.
13+
- The key data.
14+
15+
<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>
16+
17+
<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>
18+
19+
<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>
20+
21+
<br>
22+
<h1>Using Hash++</h1>
23+
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.
24+
25+
```
26+
static hashpp::hash getHMAC(hashpp::ALGORITHMS algorithm, const std::string& key, const std::string& data;
27+
static hashpp::hashCollection getHMACs(const HMAC_DataContainer& keyDataSet);
28+
static hashpp::hashCollection getHMACs(const std::vector<HMAC_DataContainer>& keyDataSets);
29+
static hashpp::hashCollection getHMACs(const std::initializer_list<HMAC_DataContainer>& keyDataSets);
30+
template <class... _Ts, ...> static hashpp::hashCollection getHMACs(hashpp::ALGORITHMS algorithm, const std::string& key, const _Ts&... data);
31+
```
32+
33+
<br>
34+
You can easily generate an HMAC for a single piece of data using Hash++. See below for an example.
35+
https://github.com/D7EAD/HashPlusPlus/blob/0ac434933e4d54b584b810d863a9f1a4a4f5f7b4/documentation/HMACs/getHMAC/getHMAC_usage.cpp#L10-L29
36+
37+
<br>
38+
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.
39+
https://github.com/D7EAD/HashPlusPlus/blob/fc5edb76cd829794a3fb34c416df7431653044e0/documentation/HMACs/getHMACs/getHMACs_usage.cpp#L14-L42
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
3+
Basic usage of Hash++ getHMAC method.
4+
This file shows basic usage of the above described method
5+
and its overloads, as well as how data can be extracted
6+
from its returned object.
7+
8+
*/
9+
10+
#include "hashpp.h"
11+
12+
using namespace hashpp;
13+
14+
int main() {
15+
// data we want to get HMAC of
16+
std::string dataToHash = "Hello World!";
17+
18+
// key to use for HMAC
19+
std::string key = "secret";
20+
21+
// get HMAC of dataToHash using SHA-256
22+
auto hmac = get::getHMAC(ALGORITHMS::SHA2_256, key, dataToHash);
23+
24+
// print out the hash
25+
std::cout << "HMAC: " << hmac << std::endl;
26+
27+
// output:
28+
// 6fa7b4dea28ee348df10f9bb595ad985ff150a4adfd6131cca677d9acee07dc6
29+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
3+
Basic usage of Hash++ getHMACs method.
4+
This file shows basic usage of the above described method
5+
and its overloads, as well as how data can be extracted
6+
from its returned object.
7+
8+
*/
9+
10+
#include "hashpp.h"
11+
12+
using namespace hashpp;
13+
14+
int main() {
15+
// create HMAC_DataContainer object
16+
// to store algorithm to use, key,
17+
// and data to HMAC
18+
HMAC_DataContainer hmac_container;
19+
20+
// set algorithm to use
21+
hmac_container.setAlgorithm(ALGORITHMS::SHA2_256);
22+
23+
// set key to use
24+
hmac_container.setKey("secretKey");
25+
26+
// set data to HMAC
27+
hmac_container.setData("dataToHMAC1", "dataToHMAC2", "dataToHMAC3");
28+
29+
// calculate the HMACs for all data in container
30+
// using key and algorithm specified
31+
hashCollection hmacs = get::getHMACs(hmac_container);
32+
33+
// parse and print each HMAC
34+
for (auto& hmac : hmacs["SHA2-256"]) {
35+
std::cout << hmac << std::endl;
36+
}
37+
38+
// output:
39+
// f0dfad2b51176704f8fff07e2c6063417b1d361465b4f9eaacf9b756037bb815
40+
// bf912338f4c9d21eff351d085a26b9723eb0da6582039d18a003046c3ae3fbef
41+
// abba2bd3400c1b03322fac45539462241ca6ae14a81d58e1db017a9bcb3947b2
42+
}

documentation/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<h1>Documentation</h1>
2+
<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.
3+
<br><br>
4+
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>.
5+
6+
- <a href="/hashing">Hashing Documentation</a>
7+
- Covers basic hashing concepts and how to generate them using the library.
8+
- <a href="/HMACs">HMAC Documentation</a>
9+
- Covers basic HMAC concepts and how to generate them using the library.
10+
- <a href="/file_hashing">File-hashing Documentation</a>
11+
- Covers how to hash files using the library.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<h1>Using Hash++ to Generate File Hashes</h1>
2+
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.
3+
4+
```
5+
static hashpp::hash getFileHash(hashpp::ALGORITHMS algorithm, const std::string& path);
6+
static hashpp::hashCollection getFilesHashes(const FilePathsContainer& filePathSet);
7+
static hashpp::hashCollection getFilesHashes(const std::vector<FilePathsContainer>& filePathSets);
8+
static hashpp::hashCollection getFilesHashes(const std::initializer_list<FilePathsContainer>& filePathSets);
9+
```
10+
11+
<br>
12+
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.
13+
https://github.com/D7EAD/HashPlusPlus/blob/ba418167da59826cda2a18990a90cf332d75308e/documentation/file_hashing/getFileHash/getFileHash_usage.cpp#L10-L29
14+
15+
<br>
16+
If you're in the business of hashing multiple files at once, you can find an example of such a use below.
17+
https://github.com/D7EAD/HashPlusPlus/blob/c007af7d81bdf054a389314ad1d7bbb6d0757262/documentation/file_hashing/getFilesHashes/getFilesHashes_usage.cpp#L14-L35
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
3+
Basic usage of Hash++ getFileHash method.
4+
This file shows basic usage of the above described method
5+
and its overloads, as well as how data can be extracted
6+
from its returned object.
7+
8+
*/
9+
10+
#include "hashpp.h"
11+
12+
using namespace hashpp;
13+
14+
int main() {
15+
// path to file we want to hash (test.txt)
16+
std::string pathToFile = "N:/source/test.txt";
17+
18+
// store the resulting hash object of the file using SHA-256
19+
auto hash = get::getFileHash(ALGORITHMS::SHA2_256, pathToFile);
20+
21+
// print the hash digest
22+
std::cout << hash << std::endl;
23+
24+
// or we can be more specific...
25+
std::cout << hash.getString() << std::endl;
26+
27+
// output:
28+
// 4de0d727216e14760010efdb0cccf577853d7da4e122a507b422148940f4aa34
29+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
A hash a day keeps the doctor away.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
3+
Basic usage of Hash++ getFileHashes method.
4+
This file shows basic usage of the above described method
5+
and its overloads, as well as how data can be extracted
6+
from its returned object.
7+
8+
*/
9+
10+
#include "hashpp.h"
11+
12+
using namespace hashpp;
13+
14+
int main() {
15+
// create a FilePathsContainer object
16+
FilePathsContainer path_cont1;
17+
18+
// set its algorithm and some paths
19+
path_cont1.setAlgorithm(ALGORITHMS::SHA2_256);
20+
path_cont1.setData("N:/source/test.txt", "N:/source/test2.txt", "N:/source/test3.txt");
21+
22+
// get the hashes of each file via get::getFilesHashes
23+
// and store them in a hashCollection object
24+
hashCollection hashes = get::getFilesHashes(path_cont1);
25+
26+
// parse and print the hashes
27+
for (auto& hash : hashes["SHA2-256"]) {
28+
std::cout << hash << std::endl;
29+
}
30+
31+
// output:
32+
// 4de0d727216e14760010efdb0cccf577853d7da4e122a507b422148940f4aa34
33+
// 7c88d6bc28e9bd6660b96cfa3b69cdbaaaf0187047267106842841357ac03bd8
34+
// 44d25e664ce6d6e82beb7a14fe312d7c09c5dc107668a6d40449bc24938e5c73
35+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
A hash a day keeps the doctor away.

0 commit comments

Comments
 (0)