34#error "missing OpenSSL Library"
41#include <openssl/aes.h>
42#include <openssl/buffer.h>
43#include <openssl/ec.h>
44#include <openssl/evp.h>
45#include <openssl/hmac.h>
46#include <openssl/md5.h>
47#include <openssl/pem.h>
48#include <openssl/rand.h>
49#include <openssl/rsa.h>
50#include <openssl/sha.h>
70round(
double x)
noexcept {
71 return floor(x + 0.5);
85 const static std::size_t buffer_size = 131072;
92 constexpr static const std::string_view
range_alpha =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
93 "abcdefghijklmnopqrstuvwxyz";
97 "abcdefghijklmnopqrstuvwxyz";
101 "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
106 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
107 "abcdefghijklmnopqrstuvwxyz";
112 " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
113 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
114 "abcdefghijklmnopqrstuvwxyz";
124 "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
125 "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
126 "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F"
127 "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F"
128 "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F"
129 "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F"
130 "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F"
131 "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F"
132 "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
133 "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
134 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
135 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF"
136 "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF"
137 "\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF"
138 "\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF"
139 "\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF";
173 template <
typename T = std::mt19937>
176 auto constexpr seed_bytes =
sizeof(
typename T::result_type) * T::state_size;
177 auto constexpr seed_len = seed_bytes /
sizeof(std::seed_seq::result_type);
178 auto seed = std::array<std::seed_seq::result_type, seed_len>();
179 auto dev = std::random_device();
180 std::generate_n(std::begin(seed), seed_len, std::ref(dev));
181 auto seed_seq = std::seed_seq(std::begin(seed), std::end(seed));
196 template <
typename T>
200 auto dist = std::uniform_int_distribution{{}, range.size() - 1};
201 auto result = std::string(len,
'\0');
202 std::generate_n(std::begin(result), len, [&]() {
return range[dist(rng)]; });
218 template <
typename T, std::
size_t N>
244 static std::string
encode(
const std::string &input)
noexcept;
303 static std::string
evp(std::istream &stream,
const EVP_MD *md)
noexcept;
315 static std::string
md5(
const std::string &input,
316 std::size_t iterations = 1) noexcept;
328 static std::
string md5(std::istream &stream, std::
size_t iterations = 1) noexcept;
340 static std::
string sha1(const std::
string &input,
341 std::
size_t iterations = 1) noexcept;
353 static std::
string sha1(std::istream &stream, std::
size_t iterations = 1) noexcept;
365 static std::
string sha256(const std::
string &input,
366 std::
size_t iterations = 1) noexcept;
378 static std::
string sha256(std::istream &stream, std::
size_t iterations = 1) noexcept;
390 static std::
string sha512(const std::
string &input,
391 std::
size_t iterations = 1) noexcept;
403 static std::
string sha512(std::istream &stream, std::
size_t iterations = 1) noexcept;
417 static std::
string pbkdf2(const std::
string &password, const std::
string &salt,
418 int iterations,
int key_size) noexcept;
451 static std::vector<
unsigned char>
hmac_sha256(const std::vector<
unsigned char> &key,
452 const std::
string &data);
462 static std::vector<
unsigned char>
sha256(const std::vector<
unsigned char> &data);
474 static std::vector<
unsigned char>
xor_bytes(const std::vector<
unsigned char> &a,
475 const std::vector<
unsigned char> &b);
520 static std::vector<
unsigned char>
521 encrypt(const std::vector<
unsigned char> &plaintext,
522 const std::vector<
unsigned char> &key, const std::vector<
unsigned char> &iv,
538 static std::vector<unsigned char>
539 decrypt(
const std::vector<unsigned char> &ciphertext,
540 const std::vector<unsigned char> &key,
const std::vector<unsigned char> &iv,
550 static std::vector<unsigned char>
hash(
const std::vector<unsigned char> &data,
561 static std::vector<unsigned char>
hmac(
const std::vector<unsigned char> &data,
562 const std::vector<unsigned char> &key,
579 static std::pair<std::string, std::string>
590 static std::vector<unsigned char>
591 rsa_sign(
const std::vector<unsigned char> &data,
const std::string &private_key,
603 static bool rsa_verify(
const std::vector<unsigned char> &data,
604 const std::vector<unsigned char> &signature,
605 const std::string &public_key,
616 static std::vector<unsigned char>
617 ec_sign(
const std::vector<unsigned char> &data,
const std::string &private_key,
629 static bool ec_verify(
const std::vector<unsigned char> &data,
630 const std::vector<unsigned char> &signature,
631 const std::string &public_key,
641 static std::vector<unsigned char>
643 const std::string &peer_public_key);
663 struct Argon2Params {
709 static std::vector<unsigned char>
728 static std::vector<unsigned char>
729 hkdf(
const std::vector<unsigned char> &input_key_material,
730 const std::vector<unsigned char> &salt,
const std::vector<unsigned char> &info,
731 size_t output_length,
DigestAlgorithm digest = DigestAlgorithm::SHA256);
750 static std::vector<unsigned char>
751 derive_key(
const std::string &password,
const std::vector<unsigned char> &salt,
753 int iterations = 10000,
769 static std::vector<unsigned char>
771 const std::string &recipient_public_key,
786 static std::vector<unsigned char>
788 const std::string &private_key,
ECIESMode mode = ECIESMode::AES_GCM,
806 const std::string &recipient_public_key,
820 static std::vector<unsigned char>
835 const std::vector<unsigned char> &b);
849 const std::vector<unsigned char> &key,
863 const std::vector<unsigned char> &key);
927 static std::pair<std::vector<unsigned char>, std::vector<unsigned char>>
939 static std::vector<unsigned char>
940 ed25519_sign(
const std::vector<unsigned char> &data,
const std::string &private_key);
951 static std::vector<unsigned char>
953 const std::vector<unsigned char> &private_key);
966 const std::vector<unsigned char> &signature,
967 const std::string &public_key);
980 const std::vector<unsigned char> &signature,
981 const std::vector<unsigned char> &public_key);
1000 static std::pair<std::vector<unsigned char>, std::vector<unsigned char>>
1012 static std::vector<unsigned char>
1014 const std::vector<unsigned char> &peer_public_key);
1025 static std::vector<unsigned char>
1027 const std::string &peer_public_key_pem);
1054 const std::vector<unsigned char> &plaintext,
1055 const std::vector<unsigned char> &key,
const std::string &metadata,
1070 static std::optional<std::pair<std::vector<unsigned char>, std::string>>
1072 const std::string &ciphertext,
const std::vector<unsigned char> &key,
1078 static std::pair<std::vector<unsigned char>, std::vector<unsigned char>>
1080 const std::vector<unsigned char> &recipient_public_key,
1081 const std::vector<unsigned char> &optional_shared_info = {},
1085 static std::vector<unsigned char>
1086 ecies_decrypt(
const std::vector<unsigned char> &encrypted_data,
1087 const std::vector<unsigned char> &ephemeral_public_key,
1088 const std::vector<unsigned char> &recipient_private_key,
1089 const std::vector<unsigned char> &optional_shared_info = {},
Base64 encoding and decoding utilities.
Definition crypto.h:233
static std::string decode(const std::string &base64) noexcept
Decode a Base64 string.
static std::string encode(const std::string &input) noexcept
Encode a string to Base64.
Provides cryptographic operations and utilities.
Definition crypto.h:83
static std::vector< unsigned char > generate_iv(SymmetricAlgorithm algorithm)
Generate a random initialization vector (IV)
static std::vector< unsigned char > ed25519_sign(const std::vector< unsigned char > &data, const std::vector< unsigned char > &private_key)
Sign data using Ed25519 with raw private key bytes.
static std::vector< unsigned char > decrypt(const std::vector< unsigned char > &ciphertext, const std::vector< unsigned char > &key, const std::vector< unsigned char > &iv, SymmetricAlgorithm algorithm, const std::vector< unsigned char > &aad={})
Decrypt data using a symmetric algorithm.
Argon2Variant
Variants of the Argon2 algorithm.
Definition crypto.h:676
static std::vector< unsigned char > generate_random_bytes(size_t size)
Generate cryptographically secure random bytes.
static std::string sha1(const std::string &input, std::size_t iterations=1) noexcept
Calculate a SHA-1 hash of a string.
static bool ed25519_verify(const std::vector< unsigned char > &data, const std::vector< unsigned char > &signature, const std::string &public_key)
Verify Ed25519 signature.
static constexpr const std::string_view range_hex_lower
Character range for lowercase hexadecimal values (0-9, a-f)
Definition crypto.h:120
static bool ed25519_verify(const std::vector< unsigned char > &data, const std::vector< unsigned char > &signature, const std::vector< unsigned char > &public_key)
Verify Ed25519 signature with raw public key bytes.
static std::string envelope_encrypt(const std::vector< unsigned char > &plaintext, const std::string &recipient_public_key, SymmetricAlgorithm algorithm=SymmetricAlgorithm::AES_256_GCM, EnvelopeFormat format=EnvelopeFormat::BASE64)
Envelope encryption.
static std::vector< unsigned char > hkdf(const std::vector< unsigned char > &input_key_material, const std::vector< unsigned char > &salt, const std::vector< unsigned char > &info, size_t output_length, DigestAlgorithm digest=DigestAlgorithm::SHA256)
Key derivation with HKDF (HMAC-based Key Derivation Function)
SymmetricAlgorithm
Supported symmetric cipher algorithms.
Definition crypto.h:142
static int hex_value(unsigned char hex_digit) noexcept
Get the numeric value of a hexadecimal digit.
static constexpr const std::string_view range_byte
Character range for binary bytes (0-255)
Definition crypto.h:123
static bool ec_verify(const std::vector< unsigned char > &data, const std::vector< unsigned char > &signature, const std::string &public_key, DigestAlgorithm digest=DigestAlgorithm::SHA256)
Verify an EC signature.
static bool constant_time_compare(const std::vector< unsigned char > &a, const std::vector< unsigned char > &b)
Secure string comparison (resistant to timing attacks)
static std::string evp(std::istream &stream, const EVP_MD *md) noexcept
Calculate a hash from an input stream using a specified digest algorithm.
static std::string pbkdf2(const std::string &password, const std::string &salt, int iterations, int key_size) noexcept
Derive a key using PBKDF2.
static std::string to_hex_string(const std::string &input, std::string_view const &range=range_hex_upper) noexcept
Convert a binary string to a hexadecimal string.
static bool verify_password(const std::string &password, const std::string &hash)
Verify a password against a stored hash.
static std::vector< unsigned char > ecies_encrypt(const std::vector< unsigned char > &plaintext, const std::string &recipient_public_key, ECIESMode mode=ECIESMode::AES_GCM, DigestAlgorithm digest=DigestAlgorithm::SHA256)
Integrated Elliptic Curve Encryption (ECIES)
static constexpr const std::string_view range_alpha_upper
Character range for uppercase alphabetic values (A-Z)
Definition crypto.h:100
static bool secure_random_fill(std::vector< unsigned char > &buffer)
Fill a vector with secure random bytes.
static std::string generate_random_string(std::size_t len, T const &range)
Generate a random string using characters from the specified range.
Definition crypto.h:198
static std::optional< std::pair< std::vector< unsigned char >, std::string > > decrypt_with_metadata(const std::string &ciphertext, const std::vector< unsigned char > &key, SymmetricAlgorithm algorithm=SymmetricAlgorithm::AES_256_GCM)
Decryption and verification of data and metadata integrity.
static const EVP_MD * get_evp_md(DigestAlgorithm algorithm)
Convert a digest algorithm enum to its corresponding EVP_MD.
static std::string md5(const std::string &input, std::size_t iterations=1) noexcept
Calculate an MD5 hash of a string.
static std::vector< unsigned char > ed25519_sign(const std::vector< unsigned char > &data, const std::string &private_key)
Sign data using Ed25519 private key.
static auto random_generator()
Create a cryptographically secure random number generator.
Definition crypto.h:175
static std::vector< unsigned char > generate_unique_iv(size_t size=12)
Random initialization vector for one-time use.
static std::string hex_to_string(const std::string &input) noexcept
Convert a hexadecimal string to a formatted string.
static std::vector< unsigned char > hash(const std::vector< unsigned char > &data, DigestAlgorithm algorithm)
Compute a generic hash using the specified algorithm.
static std::vector< unsigned char > generate_key(SymmetricAlgorithm algorithm)
Generate a random key.
static std::vector< unsigned char > encrypt(const std::vector< unsigned char > &plaintext, const std::vector< unsigned char > &key, const std::vector< unsigned char > &iv, SymmetricAlgorithm algorithm, const std::vector< unsigned char > &aad={})
Encrypt data using a symmetric algorithm.
static std::vector< unsigned char > argon2_kdf(const std::string &password, size_t key_length, const Argon2Params ¶ms, Argon2Variant variant=Argon2Variant::Argon2id)
Key derivation based on Argon2.
static std::vector< unsigned char > rsa_sign(const std::vector< unsigned char > &data, const std::string &private_key, DigestAlgorithm digest=DigestAlgorithm::SHA256)
Sign data using an RSA private key.
static constexpr const std::string_view range_hex_upper
Character range for uppercase hexadecimal values (0-9, A-F)
Definition crypto.h:117
static std::vector< unsigned char > ecdh_derive_secret(const std::string &private_key, const std::string &peer_public_key)
Derive a shared secret using ECDH.
static constexpr const std::string_view range_alpha_lower
Character range for lowercase alphabetic values (a-z)
Definition crypto.h:96
static std::pair< std::vector< unsigned char >, std::vector< unsigned char > > generate_x25519_keypair_bytes()
Generate X25519 keypair returning raw byte vectors.
static std::pair< std::string, std::string > generate_x25519_keypair()
Generate X25519 key pair for key exchange.
static std::vector< unsigned char > base64url_decode(const std::string &input)
Base64URL decode.
static bool rsa_verify(const std::vector< unsigned char > &data, const std::vector< unsigned char > &signature, const std::string &public_key, DigestAlgorithm digest=DigestAlgorithm::SHA256)
Verify an RSA signature.
static constexpr const std::string_view range_alpha
Character range for alphabetic values (A-Z, a-z)
Definition crypto.h:92
EnvelopeFormat
Format for envelope encryption outputs.
Definition crypto.h:690
static std::vector< unsigned char > hmac(const std::vector< unsigned char > &data, const std::vector< unsigned char > &key, DigestAlgorithm algorithm)
Compute an HMAC using the specified algorithm.
static std::vector< unsigned char > ec_sign(const std::vector< unsigned char > &data, const std::string &private_key, DigestAlgorithm digest=DigestAlgorithm::SHA256)
Sign data using an EC private key.
static std::pair< std::string, std::string > generate_ec_keypair(const std::string &curve="prime256v1")
Generate an EC key pair.
DigestAlgorithm
Supported digest algorithms.
Definition crypto.h:153
static std::string base64_encode(const unsigned char *data, size_t len)
Encode binary data to Base64.
static constexpr const std::string_view range_alpha_numeric
Character range for alphanumeric values (0-9, A-Z, a-z)
Definition crypto.h:104
static std::vector< unsigned char > xor_bytes(const std::vector< unsigned char > &a, const std::vector< unsigned char > &b)
XOR two byte arrays.
static std::vector< unsigned char > base64_decode(const std::string &input)
Decode a Base64 string to binary data.
static std::vector< unsigned char > derive_key(const std::string &password, const std::vector< unsigned char > &salt, size_t key_length, KdfAlgorithm algorithm=KdfAlgorithm::Argon2, int iterations=10000, const Argon2Params &argon2_params=Argon2Params())
High-level function to derive a key from a password.
KdfAlgorithm
Key derivation algorithms.
Definition crypto.h:684
std::string generate_random_string(std::size_t len, const T range[N])
Generate a random string using characters from the specified array.
Definition crypto.h:220
static std::pair< std::string, std::string > generate_ed25519_keypair()
Generate Ed25519 signing key pair.
static std::string generate_token(const std::string &payload, const std::vector< unsigned char > &key, uint64_t ttl=0)
Generate a secure token with optional TTL.
ECIESMode
Operation modes for elliptic curve encryption.
Definition crypto.h:687
static std::vector< unsigned char > generate_salt(size_t length)
Generate a secure random salt.
static std::string verify_token(const std::string &token, const std::vector< unsigned char > &key)
Verify and decrypt a token.
static std::vector< unsigned char > x25519_key_exchange(const std::string &private_key_pem, const std::string &peer_public_key_pem)
X25519 key exchange with PEM keys.
static std::string sha512(const std::string &input, std::size_t iterations=1) noexcept
Calculate a SHA-512 hash of a string.
static std::string base64url_encode(const std::vector< unsigned char > &data)
Base64URL encode.
static std::vector< unsigned char > envelope_decrypt(const std::string &ciphertext, const std::string &private_key, EnvelopeFormat format=EnvelopeFormat::BASE64)
Envelope decryption.
static constexpr const std::string_view range_numeric
Character range for numeric values (0-9)
Definition crypto.h:89
static std::vector< unsigned char > x25519_key_exchange(const std::vector< unsigned char > &private_key, const std::vector< unsigned char > &peer_public_key)
X25519 key exchange.
static std::vector< unsigned char > ecies_decrypt(const std::vector< unsigned char > &ciphertext, const std::string &private_key, ECIESMode mode=ECIESMode::AES_GCM, DigestAlgorithm digest=DigestAlgorithm::SHA256)
ECIES decryption.
static std::string sha256(const std::string &input, std::size_t iterations=1) noexcept
Calculate a SHA-256 hash of a string.
static std::string encrypt_with_metadata(const std::vector< unsigned char > &plaintext, const std::vector< unsigned char > &key, const std::string &metadata, SymmetricAlgorithm algorithm=SymmetricAlgorithm::AES_256_GCM)
Authenticated encryption of data with additional authentication.
static std::vector< unsigned char > hmac_sha256(const std::vector< unsigned char > &key, const std::string &data)
Calculate an HMAC-SHA256 hash.
static std::string hash_password(const std::string &password, Argon2Variant variant=Argon2Variant::Argon2id)
Hash a password securely using Argon2.
static constexpr const std::string_view range_alpha_numeric_special
Character range for alphanumeric values and special characters.
Definition crypto.h:110
static std::pair< std::vector< unsigned char >, std::vector< unsigned char > > generate_ed25519_keypair_bytes()
Generate Ed25519 keypair returning raw byte vectors.
static std::pair< std::string, std::string > generate_rsa_keypair(int bits=2048)
Generate an RSA key pair.
Namespace containing algorithm constants and utilities.
Parameters for the Argon2 algorithm.
Definition crypto.h:663
std::string salt
Salt for the hash function.
Definition crypto.h:667
uint32_t parallelism
Degree of parallelism (number of threads).
Definition crypto.h:666
uint32_t m_cost
Memory cost in KiB (kilobytes).
Definition crypto.h:665
uint32_t t_cost
Time cost (number of iterations, e.g., passes over memory).
Definition crypto.h:664