Modern C++20 OpenSSL Wrapper Library - A comprehensive, type-safe cryptographic library built on OpenSSL 3.0+
- SHA-1: Legacy support (160-bit)
- SHA-2 Family: SHA-224, SHA-256, SHA-384, SHA-512
- SHA-3 Family: SHA3-224, SHA3-256, SHA3-384, SHA3-512 (FIPS 202)
- Streaming API for large data
- Unified interface with CRTP pattern
- AES-CBC: Block cipher with PKCS#7 padding
- AES-CTR: Counter mode (stream cipher, parallelizable)
- AES-GCM: Authenticated encryption (AEAD, recommended)
- Key sizes: 128, 192, 256 bits
- Automatic random IV/nonce generation
- Secure key generation
- RSA: 2048/4096-bit encryption and digital signatures
- ECDSA: Elliptic curve signatures (secp256k1, P-256/384/521)
- PEM file I/O with optional password protection (AES-256-CBC)
- OAEP padding for RSA encryption
- SHA-256 based signatures
- Base64: RFC 4648 compliant encoding/decoding
- Binary-safe operations
- RAII: Automatic resource management for all OpenSSL objects
- Error Handling: C++23
std::expected-styleresult<T>type - Type Safety: C++20 concepts for compile-time checks
- Header-Only: Easy integration
- Exception-Free: All errors returned via result types
- Modern C++: Leverages C++20 features (concepts, std::span, constexpr)
- C++20 compatible compiler (GCC 10+, Clang 13+, MSVC 2019+)
- OpenSSL 3.0+ (earlier versions not supported)
- CMake 3.20+ (for building examples)
# Clone the repository
git clone https://github.com/yourusername/crypto_utils.git
cd crypto_utils
# Build examples
cmake -B build
cmake --build build
# Run examples
./build/examples/example_hash
./build/examples/example_cipher
./build/examples/example_asymmetric#include "crypto_utils.hpp"
using namespace crypto_utils;
// Simple hash
auto result = hash::sha256::hash("Hello, World!");
if (result) {
const auto& digest = *result; // std::vector<std::byte>
// Use digest...
} else {
std::cerr << "Error: " << result.error_value().message() << "\n";
}
// Streaming hash for large data
hash::sha256::streaming_context ctx;
ctx.update(chunk1);
ctx.update(chunk2);
auto digest = ctx.finalize();using namespace crypto_utils;
// Generate random 256-bit key
auto key = cipher::aes_key<cipher::aes_key_size::aes_256>::generate_random();
// Encrypt
auto enc_result = cipher::aes_256_cbc::encrypt(plaintext, *key);
if (enc_result) {
auto& enc = *enc_result;
// enc.ciphertext and enc.iv must both be saved
// Decrypt
auto dec_result = cipher::aes_256_cbc::decrypt(enc, *key);
if (dec_result) {
// Decryption successful
}
}using namespace crypto_utils;
auto key = cipher::aes_key<cipher::aes_key_size::aes_256>::generate_random();
// Optional additional authenticated data (not encrypted, but authenticated)
std::string aad = "header-info";
// Encrypt
auto enc_result = cipher::aes_256_gcm::encrypt(
plaintext, *key, std::as_bytes(std::span(aad))
);
if (enc_result) {
auto& enc = *enc_result;
// Save enc.ciphertext, enc.iv, and enc.tag
// Decrypt with authentication
auto dec_result = cipher::aes_256_gcm::decrypt(
enc, *key, std::as_bytes(std::span(aad))
);
if (!dec_result) {
// Authentication failed - data was tampered with!
}
}using namespace crypto_utils;
// Generate 2048-bit RSA key pair
auto key_result = asymmetric::rsa::generate_key_pair(2048);
auto key_pair = *key_result;
// Save keys (private key encrypted with AES-256-CBC)
key_pair.save_public_key("public.pem");
key_pair.save_private_key("private.pem", "password");
// Encrypt
auto ciphertext = asymmetric::rsa::encrypt(message, key_pair);
// Decrypt
auto plaintext = asymmetric::rsa::decrypt(*ciphertext, key_pair);
// Sign
auto signature = asymmetric::rsa::sign(document, key_pair);
// Verify
auto verified = asymmetric::rsa::verify(document, *signature, key_pair);
if (verified && *verified) {
std::cout << "Signature valid!\n";
}using namespace crypto_utils;
// Generate ECDSA key pair (P-256 curve)
auto key_result = asymmetric::ecdsa::generate_key_pair(
asymmetric::ec_curve::secp256r1
);
auto key_pair = *key_result;
// Sign
auto signature = asymmetric::ecdsa::sign(message, key_pair);
// Verify
auto verified = asymmetric::ecdsa::verify(message, *signature, key_pair);using namespace crypto_utils;
auto encoded = encoding::base64::encode(data);
auto decoded = encoding::base64::decode(*encoded);All operations return result<T> which can be checked:
auto result = hash::sha256::hash(data);
// Check if successful
if (result) {
// Success - access value
auto& value = *result;
}
// Check for errors
if (!result) {
// Error occurred
const auto& err = result.error_value();
std::cerr << "Error: " << err.message() << "\n";
std::cerr << "OpenSSL: " << err.openssl_error() << "\n";
}
// Alternative: use has_value()
if (result.has_value()) {
auto& value = result.value();
}| Category | Algorithm | Key Sizes | Notes |
|---|---|---|---|
| Hash | SHA-1 | - | Legacy, not recommended |
| Hash | SHA-2 | - | SHA-224/256/384/512 |
| Hash | SHA-3 | - | SHA3-224/256/384/512 (FIPS 202) |
| Cipher | AES-CBC | 128/192/256 | PKCS#7 padding |
| Cipher | AES-CTR | 128/192/256 | Stream cipher mode |
| Cipher | AES-GCM | 128/192/256 | AEAD, recommended |
| Asymmetric | RSA | 2048/4096 | OAEP padding, SHA-256 |
| Asymmetric | ECDSA | - | secp256k1, P-256/384/521 |
| Encoding | Base64 | - | RFC 4648 |
- Random IV/Nonce Generation: Every encryption uses a cryptographically secure random IV
- Authenticated Encryption: AES-GCM provides both confidentiality and authenticity
- Secure Padding: OAEP for RSA, PKCS#7 for CBC mode
- Modern Algorithms: SHA-3, AES-GCM, ECDSA support
- No Deprecated APIs: All OpenSSL 3.0+ modern APIs
- Key Protection: Private keys encrypted with AES-256-CBC (not 3DES)
- SHA-1: Deprecated for security-critical applications (collision attacks). Use SHA-256 or SHA-3.
- Key Management: Securely store and manage encryption keys. This library does not provide key management.
- Password Storage: Never encrypt passwords - use proper password hashing (bcrypt, argon2, etc.)
- Random Number Generation: Uses OpenSSL's CSPRNG (
RAND_bytes)
crypto_utils/
โโโ crypto_utils.hpp # Main header (include this)
โโโ include/crypto_utils/
โ โโโ core/ # Core infrastructure
โ โ โโโ openssl_ptr.hpp # RAII wrappers
โ โ โโโ error.hpp # Error codes & info
โ โ โโโ result.hpp # result<T> type
โ โ โโโ concepts.hpp # C++20 concepts
โ โโโ hash/ # Hash algorithms
โ โ โโโ hash_algorithm.hpp # Unified interface
โ โ โโโ sha1.hpp
โ โ โโโ sha2.hpp
โ โ โโโ sha3.hpp
โ โโโ cipher/ # Symmetric ciphers
โ โ โโโ aes_common.hpp
โ โ โโโ aes_cbc.hpp
โ โ โโโ aes_ctr.hpp
โ โ โโโ aes_gcm.hpp
โ โโโ asymmetric/ # Public-key crypto
โ โ โโโ key_pair.hpp
โ โ โโโ rsa.hpp
โ โ โโโ ecdsa.hpp
โ โโโ encoding/
โ โโโ base64.hpp
โโโ examples/ # Usage examples
โโโ CMakeLists.txt
| v1.x | v2.0 | Notes |
|---|---|---|
cu::sha2::hash<256>(...) |
crypto_utils::hash::sha256::hash(...) |
Namespace & API change |
cu_result |
result<byte_vector> |
New error handling |
result.is_invalid() |
!result or !result.has_value() |
Inverted logic |
| AES with fixed IV | AES with random IV per encryption | Security fix |
| 3DES key encryption | AES-256-CBC key encryption | Security improvement |
- Namespace:
cu::โcrypto_utils:: - Error Handling: Boolean returns โ
result<T>with detailed errors - AES IV: Now returns
encrypted_data{ciphertext, iv}- both must be saved - Type Safety: C++20 concepts enforce correct types at compile time
- Header Location: Single
crypto_utils.hppincludes everything
See detailed migration guide for step-by-step instructions.
// Just include the main header
#include "crypto_utils.hpp"
// Link against OpenSSL
// g++ -std=c++20 your_app.cpp -lssl -lcryptofind_package(crypto_utils REQUIRED)
target_link_libraries(your_target PRIVATE crypto_utils::crypto_utils)cmake -B build -DBUILD_EXAMPLES=ON
cmake --build build
./build/examples/example_full_workflow- RAII Overhead: Negligible - modern compilers optimize away wrapper costs
- AES-GCM: Faster than CBC + HMAC for authenticated encryption
- ECDSA: Smaller keys and faster signing than RSA
- Streaming API: Efficient for large files (no memory spikes)
Contributions welcome! Please:
- Follow existing code style (C++20, RAII, error handling via result)
- Add tests for new features
- Update documentation
- Ensure OpenSSL 3.0+ compatibility
MIT License - See LICENSE file for details
- Built on OpenSSL 3.0+
- Inspired by modern C++ best practices
- CRTP pattern from Boost and other modern C++ libraries
- Issues: GitHub Issues
- Documentation: Full API Docs
crypto_utils v2.0 - Secure, Modern, Type-Safe Cryptography for C++20