44 lines
1.4 KiB
C++
44 lines
1.4 KiB
C++
#include <crypt.h>
|
||
#include <stdexcept>
|
||
#include "hashing.hpp"
|
||
#include <random>
|
||
#include <sstream>
|
||
#include <iomanip>
|
||
|
||
std::string hashing::GenerateSetting(unsigned long cost) {
|
||
// "$y$" is the yescrypt prefix
|
||
const char* setting = crypt_gensalt("$y$", cost, nullptr, 0);
|
||
if (!setting)
|
||
throw std::runtime_error("crypt_gensalt() failed – yescrypt may not be supported");
|
||
return setting;
|
||
}
|
||
|
||
std::string hashing::HashPassword(const std::string& password, const std::string& setting) {
|
||
crypt_data data{};
|
||
const char* hash = crypt_r(password.c_str(), setting.c_str(), &data);
|
||
if (!hash || hash[0] == '*')
|
||
throw std::runtime_error("crypt_r() failed");
|
||
return hash;
|
||
}
|
||
|
||
bool hashing::VerifyPassword(const std::string& password, const std::string& stored_hash) {
|
||
crypt_data data{};
|
||
const char* result = crypt_r(password.c_str(), stored_hash.c_str(), &data);
|
||
if (!result || result[0] == '*')
|
||
return false;
|
||
return stored_hash == result;
|
||
}
|
||
|
||
std::string hashing::generate_token(size_t bytes) {
|
||
std::random_device rd;
|
||
std::string token;
|
||
token.reserve(bytes * 2);
|
||
|
||
std::uniform_int_distribution<uint8_t> dist(0, 255);
|
||
for (size_t i = 0; i < bytes; ++i) {
|
||
std::ostringstream ss;
|
||
ss << std::hex << std::setw(2) << std::setfill('0') << (int)dist(rd);
|
||
token += ss.str();
|
||
}
|
||
return token;
|
||
} |