Skip to content

HMAC SHA1/SHA256/SHA512 in modern C++11. Includes time tokens and MetaTrader (MQL5) support | Библиотека HMAC для C++ и MQL5: поддержка SHA1, SHA256, SHA512 и токенов по времени

License

Notifications You must be signed in to change notification settings

NewYaroslav/hmac-cpp

Repository files navigation

A lightweight C++11 library for computing HMAC (hash-based message authentication codes), supporting SHA1, SHA256, SHA512, as well as one-time passwords compliant with HOTP (RFC 4226) and TOTP (RFC 6238).

🚀 Features

  • Compatible with C++11
  • Supports HMAC using SHA256, SHA512, SHA1
  • Outputs in binary or hex format
  • Support for time-based tokens:
    • HOTP (RFC 4226) — counter-based one-time passwords
    • TOTP (RFC 6238) — time-based one-time passwords
    • HMAC Time Tokens — lightweight HMAC-based tokens with rotation interval
  • Includes MQL5 support — adapted SHA/HMAC versions for MetaTrader
  • Static build via CMake
  • Example program included

🔧 Build and Installation

Use CMake to build:

cmake -B build -DBUILD_EXAMPLE=ON
cmake --build build

To install the library and headers:

cmake --install build --prefix _install

This will create the following structure:

_install/
├── include/hmac_cpp/
│   ├── hmac.hpp
│   ├── hmac_utils.hpp
│   ├── sha1.hpp
│   ├── sha256.hpp
│   └── sha512.hpp
└── lib/
    └── libhmac.a

Predefined .bat scripts for MinGW builds are also available: build_*.bat.

📦 MQL5 Compatibility

The repository includes sha256.mqh, sha512.mqh, hmac.mqh, and hmac_utils.mqh files, fully compatible with MetaTrader 5.

You can use the same interface inside your MQL5 scripts and experts:

#include <hmac-cpp/hmac.mqh>

string hash = hmac::get_hmac("key", "message", hmac::TypeHash::HASH_SHA256);

Usage

HMAC (string input)

std::string get_hmac(
    std::string key,
    const std::string& msg,
    const TypeHash type,
    bool is_hex = true,
    bool is_upper = false
);

Parameters:

  • key — Secret key
  • msg — Message
  • type — Hash type: hmac::TypeHash::SHA256 or SHA512
  • is_hex — Return hex string (true) or raw binary (false) [default: true]
  • is_upper — Use uppercase hex (only applies if is_hex == true) [default: false]

Returns: If is_hex == true, returns a hexadecimal string (std::string) of the HMAC. If is_hex == false, returns a raw binary HMAC as a std::string (not human-readable).

HMAC (binary data: raw buffer)

std::vector<uint8_t> get_hmac(
    const void* key_ptr,
    size_t key_len,
    const void* msg_ptr,
    size_t msg_len,
    TypeHash type
);

Parameters:

  • key_ptr — Pointer to secret key buffer
  • key_len — Length of key in bytes
  • msg_ptr — Pointer to message buffer
  • msg_len — Length of message in bytes
  • type — Hash type

Returns: Binary digest as std::vector<uint8_t>

HMAC (vectors)

template<typename T>
std::vector<uint8_t> get_hmac(
    const std::vector<T>& key,
    const std::vector<T>& msg,
    TypeHash type
);

Template requirement: T must be char or uint8_t

Parameters:

  • key — Vector containing the key
  • msg — Vector containing the message
  • type — Hash type

Returns: Binary digest as std::vector<uint8_t>

🕓 HOTP and TOTP Tokens

The library supports generating one-time passwords based on RFC 4226 and RFC 6238.

HOTP (HMAC-based One-Time Password)

#include <hmac_utils.hpp>

std::string key = "12345678901234567890"; // raw key
uint64_t counter = 0;
int otp = get_hotp_code(key, counter); // defaults: 6 digits, SHA1
std::cout << "HOTP: " << otp << std::endl;

TOTP (Time-based One-Time Password)

#include <hmac_utils.hpp>

std::string key = "12345678901234567890"; // raw key
int otp = get_totp_code(key); // defaults: 30s period, 6 digits, SHA1
std::cout << "TOTP: " << otp << std::endl;

You can also generate a code for a specific timestamp:

uint64_t time_at = 1700000000;
int otp = get_totp_code_at(key, time_at);

🕓 Time-Based HMAC Tokens (Custom HMAC Time Tokens)

The library also includes a lightweight implementation of time-based HMAC tokens, which are not directly based on RFC 4226/6238 (HOTP/TOTP). These tokens:

  • Are based on HMAC(timestamp)
  • Are returned as hex strings
  • Require no server-side state (stateless)
  • Support binding to a client fingerprint (e.g. device ID)
  • Support SHA1, SHA256, and SHA512

Example:

#include <hmac_utils.hpp>

std::string token = hmac::generate_time_token(secret_key, 60);
bool is_valid = hmac::is_token_valid(token, secret_key, 60);

You can also bind the token to a client fingerprint:

std::string token = hmac::generate_time_token(secret_key, fingerprint, 60);
bool is_valid = hmac::is_token_valid(token, secret_key, fingerprint, 60);

This is useful for stateless authentication, API protection, and one-time tokens.

📄 Example

The example is in example.cpp and is built automatically when BUILD_EXAMPLE=ON.

#include <iostream>
#include <hmac.hpp>

int main() {
    std::string input = "grape";
    std::string key = "12345";

    std::string hmac_sha256 = hmac::get_hmac(key, input, hmac::TypeHash::SHA256);
    std::cout << "HMAC-SHA256: " << hmac_sha256 << std::endl;

    std::string hmac_sha512 = hmac::get_hmac(key, input, hmac::TypeHash::SHA512);
    std::cout << "HMAC-SHA512: " << hmac_sha512 << std::endl;

    return 0;
}

📚 Resources

📝 License

This project is licensed under the MIT License. You are free to use, copy, modify, and distribute this software, provided that the original license notice is included.

See the LICENSE file for full details.

About

HMAC SHA1/SHA256/SHA512 in modern C++11. Includes time tokens and MetaTrader (MQL5) support | Библиотека HMAC для C++ и MQL5: поддержка SHA1, SHA256, SHA512 и токенов по времени

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages