33 #ifndef _IDENTT_HTTP_CRYPTO_HPP_ 34 #define _IDENTT_HTTP_CRYPTO_HPP_ 43 #include <openssl/buffer.h> 44 #include <openssl/evp.h> 45 #include <openssl/md5.h> 46 #include <openssl/sha.h> 52 #if _MSC_VER == 1700 // MSVS 2012 has no definition for round() 53 inline double round(
double x) noexcept
55 return floor(x + 0.5);
60 const static std::size_t buffer_size = 131072;
66 static std::string
encode(
const std::string &input) noexcept
71 BUF_MEM *bptr = BUF_MEM_new();
73 b64 = BIO_new(BIO_f_base64());
74 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
75 bio = BIO_new(BIO_s_mem());
77 BIO_set_mem_buf(b64, bptr, BIO_CLOSE);
80 auto base64_length =
static_cast<std::size_t
>(round(4 * ceil(static_cast<double>(input.size()) / 3.0)));
81 base64.resize(base64_length);
83 bptr->max = base64_length + 1;
84 bptr->data = &base64[0];
86 if(BIO_write(b64, &input[0], static_cast<int>(input.size())) <= 0 || BIO_flush(b64) <= 0)
100 static std::string
decode(
const std::string &base64) noexcept
105 ascii.resize((6 * base64.size()) / 8);
108 b64 = BIO_new(BIO_f_base64());
109 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
111 #if(defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER <= 0x1000115fL) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2080000fL) 112 bio = BIO_new_mem_buf((
char *)&base64[0], static_cast<int>(base64.size()));
114 bio = BIO_new_mem_buf(&base64[0], static_cast<int>(base64.size()));
116 bio = BIO_push(b64, bio);
118 auto decoded_length = BIO_read(bio, &ascii[0], static_cast<int>(ascii.size()));
119 if(decoded_length > 0)
120 ascii.resize(static_cast<std::size_t>(decoded_length));
133 std::stringstream hex_stream;
134 hex_stream << std::hex << std::internal << std::setfill(
'0');
135 for(
auto &byte : input)
136 hex_stream << std::setw(2) << static_cast<int>(
static_cast<unsigned char>(byte));
137 return hex_stream.str();
141 static std::string
md5(
const std::string &input, std::size_t iterations = 1) noexcept
145 hash.resize(128 / 8);
146 MD5(reinterpret_cast<const unsigned char *>(&input[0]), input.size(),
reinterpret_cast<unsigned char *
>(&hash[0]));
148 for(std::size_t c = 1; c < iterations; ++c)
149 MD5(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(),
reinterpret_cast<unsigned char *
>(&hash[0]));
155 static std::string
md5(std::istream &stream, std::size_t iterations = 1) noexcept
159 std::streamsize read_length;
160 std::vector<char> buffer(buffer_size);
161 while((read_length = stream.read(&buffer[0], buffer_size).gcount()) > 0)
162 MD5_Update(&context, buffer.data(),
static_cast<std::size_t
>(read_length));
164 hash.resize(128 / 8);
165 MD5_Final(reinterpret_cast<unsigned char *>(&hash[0]), &context);
167 for(std::size_t c = 1; c < iterations; ++c)
168 MD5(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(),
reinterpret_cast<unsigned char *
>(&hash[0]));
174 static std::string
sha1(
const std::string &input, std::size_t iterations = 1) noexcept
178 hash.resize(160 / 8);
179 SHA1(reinterpret_cast<const unsigned char *>(&input[0]), input.size(),
reinterpret_cast<unsigned char *
>(&hash[0]));
181 for(std::size_t c = 1; c < iterations; ++c)
182 SHA1(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(),
reinterpret_cast<unsigned char *
>(&hash[0]));
188 static std::string
sha1(std::istream &stream, std::size_t iterations = 1) noexcept
192 std::streamsize read_length;
193 std::vector<char> buffer(buffer_size);
194 while((read_length = stream.read(&buffer[0], buffer_size).gcount()) > 0)
195 SHA1_Update(&context, buffer.data(),
static_cast<std::size_t
>(read_length));
197 hash.resize(160 / 8);
198 SHA1_Final(reinterpret_cast<unsigned char *>(&hash[0]), &context);
200 for(std::size_t c = 1; c < iterations; ++c)
201 SHA1(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(),
reinterpret_cast<unsigned char *
>(&hash[0]));
207 static std::string
sha256(
const std::string &input, std::size_t iterations = 1) noexcept
211 hash.resize(256 / 8);
212 SHA256(reinterpret_cast<const unsigned char *>(&input[0]), input.size(),
reinterpret_cast<unsigned char *
>(&hash[0]));
214 for(std::size_t c = 1; c < iterations; ++c)
215 SHA256(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(),
reinterpret_cast<unsigned char *
>(&hash[0]));
221 static std::string
sha256(std::istream &stream, std::size_t iterations = 1) noexcept
224 SHA256_Init(&context);
225 std::streamsize read_length;
226 std::vector<char> buffer(buffer_size);
227 while((read_length = stream.read(&buffer[0], buffer_size).gcount()) > 0)
228 SHA256_Update(&context, buffer.data(),
static_cast<std::size_t
>(read_length));
230 hash.resize(256 / 8);
231 SHA256_Final(reinterpret_cast<unsigned char *>(&hash[0]), &context);
233 for(std::size_t c = 1; c < iterations; ++c)
234 SHA256(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(),
reinterpret_cast<unsigned char *
>(&hash[0]));
240 static std::string
sha512(
const std::string &input, std::size_t iterations = 1) noexcept
244 hash.resize(512 / 8);
245 SHA512(reinterpret_cast<const unsigned char *>(&input[0]), input.size(),
reinterpret_cast<unsigned char *
>(&hash[0]));
247 for(std::size_t c = 1; c < iterations; ++c)
248 SHA512(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(),
reinterpret_cast<unsigned char *
>(&hash[0]));
254 static std::string
sha512(std::istream &stream, std::size_t iterations = 1) noexcept
257 SHA512_Init(&context);
258 std::streamsize read_length;
259 std::vector<char> buffer(buffer_size);
260 while((read_length = stream.read(&buffer[0], buffer_size).gcount()) > 0)
261 SHA512_Update(&context, buffer.data(),
static_cast<std::size_t
>(read_length));
263 hash.resize(512 / 8);
264 SHA512_Final(reinterpret_cast<unsigned char *>(&hash[0]), &context);
266 for(std::size_t c = 1; c < iterations; ++c)
267 SHA512(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(),
reinterpret_cast<unsigned char *
>(&hash[0]));
285 static std::string
pbkdf2(
const std::string &password,
const std::string &salt,
int iterations,
int key_size) noexcept
288 key.resize(static_cast<std::size_t>(key_size));
289 PKCS5_PBKDF2_HMAC_SHA1(password.c_str(), password.size(),
290 reinterpret_cast<const unsigned char *
>(salt.c_str()), salt.size(), iterations,
291 key_size,
reinterpret_cast<unsigned char *
>(&key[0]));
static std::string to_hex_string(const std::string &input) noexcept
Returns hex string from bytes in input string.
Definition: Crypto.hpp:131
static std::string decode(const std::string &base64) noexcept
Returns Base64 decoded string from base64 input.
Definition: Crypto.hpp:100
Definition: Crypto.hpp:59
static std::string sha1(std::istream &stream, std::size_t iterations=1) noexcept
Returns sha1 hash value from input stream.
Definition: Crypto.hpp:188
static std::string pbkdf2(const std::string &password, const std::string &salt, int iterations, int key_size) noexcept
Returns PBKDF2 hash value from the given password Input parameter key_size number of bytes of the ret...
Definition: Crypto.hpp:285
Definition: Crypto.hpp:63
static std::string md5(std::istream &stream, std::size_t iterations=1) noexcept
Returns md5 hash value from input stream.
Definition: Crypto.hpp:155
static std::string sha256(std::istream &stream, std::size_t iterations=1) noexcept
Returns sha256 hash value from input stream.
Definition: Crypto.hpp:221
static std::string encode(const std::string &input) noexcept
Returns Base64 encoded string from input string.
Definition: Crypto.hpp:66
Definition: CryptoBase.hpp:49
static std::string sha1(const std::string &input, std::size_t iterations=1) noexcept
Returns sha1 hash value from input string.
Definition: Crypto.hpp:174
static std::string sha256(const std::string &input, std::size_t iterations=1) noexcept
Returns sha256 hash value from input string.
Definition: Crypto.hpp:207
static std::string sha512(const std::string &input, std::size_t iterations=1) noexcept
Returns sha512 hash value from input string.
Definition: Crypto.hpp:240
static std::string sha512(std::istream &stream, std::size_t iterations=1) noexcept
Returns sha512 hash value from input stream.
Definition: Crypto.hpp:254
static std::string md5(const std::string &input, std::size_t iterations=1) noexcept
Returns md5 hash value from input string.
Definition: Crypto.hpp:141