Skip to content

Commit 7b53221

Browse files
committed
docs(readme): clarify token validation
1 parent e11be12 commit 7b53221

4 files changed

Lines changed: 50 additions & 25 deletions

File tree

README-RU.md

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -240,14 +240,21 @@ int otp = get_totp_code_at(key, time_at);
240240
#include <hmac_cpp/hmac_utils.hpp>
241241

242242
std::string token = hmac::generate_time_token(secret_key, 60);
243-
bool is_valid = hmac::is_token_valid(token, secret_key, 60);
243+
bool is_valid = hmac::is_token_valid(user_token, secret_key, 60);
244244
```
245245

246246
Также можно привязать токен к *отпечатку клиента* (fingerprint):
247247

248248
```cpp
249249
std::string token = hmac::generate_time_token(secret_key, fingerprint, 60);
250-
bool is_valid = hmac::is_token_valid(token, secret_key, fingerprint, 60);
250+
bool is_valid = hmac::is_token_valid(user_token, secret_key, fingerprint, 60);
251+
```
252+
253+
Чтобы сравнить два токена напрямую, используйте
254+
`hmac::constant_time_equal` для защиты от атак по времени:
255+
256+
```cpp
257+
bool same = hmac::constant_time_equal(expected_token, user_token); // длины публичны
251258
```
252259

253260
Если `interval_sec` неположителен, функции выбросят `std::invalid_argument`:
@@ -269,21 +276,27 @@ try {
269276
```cpp
270277
#include <iostream>
271278
#include <hmac_cpp/hmac.hpp>
279+
#include <hmac_cpp/hmac_utils.hpp>
272280

273281
int main() {
274282
std::string input = "grape";
275283
std::string key = "12345";
276284

277-
std::string hmac_sha256 = hmac::get_hmac(key, input, hmac::TypeHash::SHA256);
278-
std::cout << "HMAC-SHA256: " << hmac_sha256 << std::endl;
279-
280-
std::string hmac_sha512 = hmac::get_hmac(key, input, hmac::TypeHash::SHA512);
281-
std::cout << "HMAC-SHA512: " << hmac_sha512 << std::endl;
285+
std::string mac = hmac::get_hmac(key, input, hmac::TypeHash::SHA256);
286+
if (hmac::constant_time_equal(mac,
287+
"7632ac2e8ddedaf4b3e7ab195fefd17571c37c970e02e169195a158ef59e53ca")) {
288+
std::cout << "MAC проверен\n";
289+
}
282290

283291
return 0;
284292
}
285293
```
286294

295+
**Примечание:** `constant_time_equal` считает длину входных данных публичной и
296+
время работы зависит от максимальной длины. Не проверяйте длины отдельно —
297+
ранние проверки могут выдать информацию через побочные каналы времени
298+
выполнения.
299+
287300
## 📚 Полезные ссылки
288301

289302
* Исходный код [SHA256](http://www.zedwood.com/article/cpp-sha256-function)

README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,14 +281,21 @@ The library also includes a **lightweight implementation of time-based HMAC toke
281281
#include <hmac_cpp/hmac_utils.hpp>
282282

283283
std::string token = hmac::generate_time_token(secret_key, 60);
284-
bool is_valid = hmac::is_token_valid(token, secret_key, 60);
284+
bool is_valid = hmac::is_token_valid(user_token, secret_key, 60);
285285
```
286286

287287
You can also bind the token to a *client fingerprint*:
288288

289289
```cpp
290290
std::string token = hmac::generate_time_token(secret_key, fingerprint, 60);
291-
bool is_valid = hmac::is_token_valid(token, secret_key, fingerprint, 60);
291+
bool is_valid = hmac::is_token_valid(user_token, secret_key, fingerprint, 60);
292+
```
293+
294+
To compare two tokens directly, use `hmac::constant_time_equal` for a
295+
timing-safe check:
296+
297+
```cpp
298+
bool same = hmac::constant_time_equal(expected_token, user_token); // lengths are public
292299
```
293300

294301
If `interval_sec` is not positive, the functions throw `std::invalid_argument`:
@@ -326,8 +333,9 @@ int main() {
326333
}
327334
```
328335

329-
**Note:** avoid checking input lengths before calling `constant_time_equal`.
330-
Early length comparisons can leak information through timing side channels.
336+
**Note:** `constant_time_equal` treats input lengths as public and may run
337+
longer for longer inputs. Avoid checking lengths separately—early length
338+
comparisons can leak information through timing side channels.
331339

332340
## 📚 Resources
333341

include/hmac_cpp/hmac_utils.hpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@ namespace hmac_cpp {
2424
HMAC_CPP_API bool constant_time_equals(const uint8_t* a, size_t a_len,
2525
const uint8_t* b, size_t b_len);
2626

27+
/// \brief Alias for \c constant_time_equals.
28+
/// \param a Pointer to first array.
29+
/// \param a_len Length of the first array.
30+
/// \param b Pointer to second array.
31+
/// \param b_len Length of the second array.
32+
/// \return true if both arrays are equal.
33+
/// \note Avoids early length checks; input lengths are treated as public
34+
/// and may influence timing.
35+
HMAC_CPP_API bool constant_time_equal(const uint8_t* a, size_t a_len,
36+
const uint8_t* b, size_t b_len);
37+
2738
/// \brief Compare vectors in constant time.
2839
/// \param a First vector.
2940
/// \param b Second vector.
@@ -42,19 +53,7 @@ namespace hmac_cpp {
4253
reinterpret_cast<const uint8_t*>(b.data()), b.size());
4354
}
4455

45-
/// \brief Alias for constant_time_equals.
46-
/// \param a Pointer to first array.
47-
/// \param a_len Length of the first array.
48-
/// \param b Pointer to second array.
49-
/// \param b_len Length of the second array.
50-
/// \return true if both arrays are equal.
51-
/// \note Avoids early length checks to mitigate timing attacks.
52-
inline bool constant_time_equal(const uint8_t* a, size_t a_len,
53-
const uint8_t* b, size_t b_len) {
54-
return constant_time_equals(a, a_len, b, b_len);
55-
}
56-
57-
/// \brief Alias for constant_time_equals on vectors.
56+
/// \brief Alias for \c constant_time_equal on vectors.
5857
/// \param a First vector.
5958
/// \param b Second vector.
6059
/// \return true if both vectors are equal.
@@ -63,7 +62,7 @@ namespace hmac_cpp {
6362
return constant_time_equal(a.data(), a.size(), b.data(), b.size());
6463
}
6564

66-
/// \brief Alias for constant_time_equals on strings.
65+
/// \brief Alias for \c constant_time_equal on strings.
6766
/// \param a First string.
6867
/// \param b Second string.
6968
/// \return true if both strings are equal.

src/hmac_utils.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ namespace hmac_cpp {
2121
return diff == 0;
2222
}
2323

24+
bool constant_time_equal(const uint8_t* a, size_t a_len,
25+
const uint8_t* b, size_t b_len) {
26+
return constant_time_equals(a, a_len, b, b_len);
27+
}
28+
2429
static TypeHash to_type_hash(Pbkdf2Hash prf) {
2530
switch (prf) {
2631
case Pbkdf2Hash::Sha1: return TypeHash::SHA1;

0 commit comments

Comments
 (0)