auth_crypto.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /*
  2. * auth_crypto.cpp - bcrypt C++ wrapper implementation
  3. */
  4. #include "auth_crypto.h"
  5. #include "bcrypt/bcrypt.h"
  6. #include <cstring>
  7. #include <cstdio>
  8. #include <fcntl.h>
  9. #include <unistd.h>
  10. namespace auth {
  11. static const int BCRYPT_COST = 12;
  12. std::string bcrypt_hash(const std::string &password) {
  13. char salt[64];
  14. char hash[128];
  15. if (bcrypt_gensalt(BCRYPT_COST, salt) != 0) return "";
  16. if (bcrypt_hashpw(password.c_str(), salt, hash) != 0) return "";
  17. return std::string(hash);
  18. }
  19. std::string bcrypt_hash_with_salt(const std::string &password, const std::string &salt) {
  20. char hash[128];
  21. if (bcrypt_hashpw(password.c_str(), salt.c_str(), hash) != 0) return "";
  22. return std::string(hash);
  23. }
  24. bool bcrypt_verify(const std::string &password, const std::string &hash) {
  25. return ::bcrypt_verify(password.c_str(), hash.c_str()) == 1;
  26. }
  27. std::string random_bytes(int byte_count) {
  28. std::string result(byte_count, '\0');
  29. int fd = open("/dev/urandom", O_RDONLY);
  30. if (fd < 0) return "";
  31. ssize_t n = read(fd, &result[0], byte_count);
  32. close(fd);
  33. if (n != byte_count) return "";
  34. return result;
  35. }
  36. static const char hex_chars[] = "0123456789abcdef";
  37. std::string random_hex(int byte_count) {
  38. std::string raw = random_bytes(byte_count);
  39. if (raw.empty()) return "";
  40. std::string hex(byte_count * 2, '\0');
  41. for (int i = 0; i < byte_count; i++) {
  42. hex[i * 2] = hex_chars[(uint8_t)raw[i] >> 4];
  43. hex[i * 2 + 1] = hex_chars[(uint8_t)raw[i] & 0x0f];
  44. }
  45. return hex;
  46. }
  47. bool secure_compare(const std::string &a, const std::string &b) {
  48. if (a.size() != b.size()) return false;
  49. volatile unsigned char result = 0;
  50. for (size_t i = 0; i < a.size(); i++) {
  51. result |= (unsigned char)a[i] ^ (unsigned char)b[i];
  52. }
  53. return result == 0;
  54. }
  55. } // namespace auth