使用密码哈希和加盐(Hashing and Salting)保护用户密码安全
方法简介
密码哈希和加盐(Hashing and Salting):将用户的密码进行哈希和加盐处理。哈希是将密码转换为固定长度的字符串,
而加盐是在哈希过程中引入随机字符串。哈希和加盐的组合可以保护用户密码的安全性,
即使数据库泄露,攻击者也很难还原出真实密码.
涉及到密码哈希和加盐的 C++ 代码编写时,可以使用任何一种常见的哈希函数库,
例如 OpenSSL,Crypto++ 或 POCO C++ 库。在这里,我们使用 Crypto++ 库来实现密码哈希和加盐。
使用场景
要求在后台用户数据中禁止直接保存明文密码。
参考案例
实际使用参考如下案例
建立两张表:
表1:用户名+盐 (注册时随机生成)
表2:用户名+哈希 (哈希由注册时的密码和盐经哈希密码函数生成)
用户注册时用用户名和密码注册,表一和表二添加相关条目;
用户登录时用用户名和密码登录,服务器拿到用户名和查表1获得盐值,然后用密码和盐值生成新的哈希,与表2中存储的哈希去匹配,匹配上说明用户密码正确,匹配不上说明用户密码错误。
代码使用示例
#include <iostream>
#include <cryptopp/osrng.h>
#include <cryptopp/sha.h>
#include <cryptopp/hex.h>
using CryptoPP::AutoSeededRandomPool;
using CryptoPP::SHA256;
using CryptoPP::HexEncoder;
std::string GenerateSalt()
{
AutoSeededRandomPool rnd;
byte salt[16];
rnd.GenerateBlock(salt, sizeof(salt));
std::string encoded;
HexEncoder encoder(new CryptoPP::StringSink(encoded));
encoder.Put(salt, sizeof(salt));
encoder.MessageEnd();
return encoded;
}
std::string HashPassword(const std::string& password, const std::string& salt)
{
std::string input = password + salt;
std::string output;
SHA256 hash;
hash.Update((const byte*)input.data(), input.size());
output.resize(hash.DigestSize());
hash.Final((byte*)&output[0]);
std::string encoded;
HexEncoder encoder(new CryptoPP::StringSink(encoded));
encoder.Put((const byte*)output.data(), output.size());
encoder.MessageEnd();
return encoded;
}
bool VerifyPassword(const std::string& password, const std::string& salt, const std::string& hashed_password)
{
std::string hash_to_verify = HashPassword(password, salt);
return hashed_password == hash_to_verify;
}
int main()
{
std::string password = "my_password";
std::string salt = GenerateSalt();
std::string hashed_password = HashPassword(password, salt);
std::cout << "Password: " << password << std::endl;
std::cout << "Salt: " << salt << std::endl;
std::cout << "Hashed password: " << hashed_password << std::endl;
bool ret = VerifyPassword(password,salt,hashed_password);
std::cout <<"match: "<<ret<<std::endl;
return 0;
}