【发布时间】:2019-07-10 12:42:10
【问题描述】:
我正在使用 C++ 创建一个简单的数据库访问应用程序,并且我添加了包含以下内容的用户表:ID、USER、PASSWORD 和 SALT,我使用 Crypto++ 作为加密后端。所以我创建了这个函数:
#include "crypto.h"
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#include <md5.h>
#include <hex.h>
#include <osrng.h>
using namespace std;
using namespace CryptoPP;
string MyCrypto::MD5(const string strMessage)
{
byte arrbyDigest[Weak::MD5::DIGESTSIZE];
Weak::MD5 hash;
hash.CalculateDigest(arrbyDigest, /*(const byte*)*/strMessage.c_str(), strMessage.length());
HexEncoder encoder;
string strOutput;
encoder.Attach(new StringSink(strOutput));
encoder.Put(arrbyDigest, sizeof(arrbyDigest));
encoder.MessageEnd();
return strOutput;
}
string MyCrypto::GenerateSalt(const size_t length /*= 16*/)
{
SecByteBlock arrbySalt(length);
AutoSeededRandomPool asrp;
asrp.GenerateBlock(arrbySalt, length);
string strSalt(arrbySalt);
strSalt.ToAscii();
return strSalt;
}
到目前为止一切正常,直到我意识到生成的盐字符串可以包含不可打印字符甚至是空终止字符
所以我的问题是:
我做对了吗?
盐的长度是16和我做的一样实用吗?
我应该在 Base 64、HEX 中加密盐字符串还是将其与之前的纯密码字符串连接时将其保留为 纯文本 MD5 哈希?
将盐字符串保存到数据库时,我应该使用Base 64、HEX还是将其保留为纯文本? p>
你有什么建议?
【问题讨论】:
-
哈希不是“加密”,MD5 也不安全。你考虑过en.wikipedia.org/wiki/Bcrypt吗? (尽管实际上在您的代码或库选择中没有任何迹象表明您确实在使用 MD5)。
-
AutoSeededRandomPool产生统一的字节流,这意味着每个字节都在[0-255]范围内。您可以使用BLOB将其直接存储在数据库中,也可以使用HexEncoder或Base64Encoder对其进行编码。对盐进行编码并不重要,因为它仍然具有相同的熵。只要您始终如一地执行此操作,您向哈希函数提供什么并不重要。您可以提供二进制数据或编码数据。一直做同样的事情。 -
@ЯрославМашко 这将限制您为所有用户提供一个盐。不好。此外,依赖于攻击者不知道您的加密方案的安全性根本不是安全性。您似乎引用的答案确实说明了所有这些。
标签: c++ cryptography md5 salt crypto++