MD5哈希的密码盐字符串的格式是什么?

问题描述 投票:-1回答:1

我正在使用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中的salt字符串,还是在MD5哈希之前将它与普通密码字符串连接时将其保留为纯文本?

我应该加密Base 64,HEX中的salt字符串,还是在将其保存到数据库时将其保留为纯文本?

你有什么建议?

c++ cryptography md5 salt crypto++
1个回答
2
投票

不,你没有以正确的方式做到这一点。 MD5是 - 或者更确切地说 - 是加密安全散列。它不能直接应用于哈希密码。要散列密码,您需要一个密码散列,其中包含随机盐和工作因子(成本或迭代次数,具体取决于所使用的密码散列)。这些的例子是bcrypt,PBKDF2和较新的Argon2。 Here是一篇随机文章,讨论密码哈希的使用。

至于编码,我总是会尝试保持现有的标准。对于密码哈希,适用的标准是Modular Crypt Format。如果您正在设计没有强互操作性要求的新方案,那么您也可以使用Password Hashing Format

两者都使用一种base 64编码作为salt和password的输出格式。一个例子是bcrypt输出$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy,其中2a表示bcrypt和格式,10是成本(工作因子),N9qo8uLOickgx2ZMRZoMye是盐的基数64编码;其余的是密码哈希。请注意,salt和密码之间没有美元符号分隔符。

我从bcrypt Wikipedia page上面得到了上面的例子,这是获取更多信息的一个有趣的起点,包括可能是crypt的MD5哈希输出(如图所示,你不应该使用)。

差点忘了,是的,16个随机字节/ 128位盐很多;如果你使用了8个字节,超过32个字节就会过度,没有人会眨眼睛。

© www.soinside.com 2019 - 2024. All rights reserved.