【问题标题】:What is the format of a Password Salt string for MD5 hash?MD5 哈希的密码盐字符串的格式是什么?
【发布时间】:2019-07-10 12:42:10
【问题描述】:

我正在使用 C++ 创建一个简单的数据库访问应用程序,并且我添加了包含以下内容的用户表:IDUSERPASSWORD 和 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 64HEX 中加密盐字符串还是将其与之前的纯密码字符串连接时将其保留为 纯文本 MD5 哈希?

将盐字符串保存到数据库时,我应该使用Base 64HEX还是将其保留为纯文本? p>

你有什么建议?

【问题讨论】:

  • 哈希不是“加密”,MD5 也不安全。你考虑过en.wikipedia.org/wiki/Bcrypt吗? (尽管实际上在您的代码或库选择中没有任何迹象表明您确实在使用 MD5)。
  • AutoSeededRandomPool 产生统一的字节流,这意味着每个字节都在[0-255] 范围内。您可以使用BLOB 将其直接存储在数据库中,也可以使用HexEncoderBase64Encoder 对其进行编码。对盐进行编码并不重要,因为它仍然具有相同的熵。只要您始终如一地执行此操作,您向哈希函数提供什么并不重要。您可以提供二进制数据或编码数据。一直做同样的事情。
  • @ЯрославМашко 这将限制您为所有用户提供一个盐。不好。此外,依赖于攻击者不知道您的加密方案的安全性根本不是安全性。您似乎引用的答案确实说明了所有这些。

标签: c++ cryptography md5 salt crypto++


【解决方案1】:

不,你的做法不对。 MD5 是 - 或者更确切地说 曾经 - 一个加密安全的散列。它不适用于哈希密码。要散列密码,您需要一个包含随机盐和工作因子(成本或迭代计数,取决于使用的密码散列)的密码散列。其中的例子是 bcrypt、PBKDF2 和更新的 Argon2。 Here 是一篇讨论密码哈希使用的随机文章。

至于编码,我总是尽量保持现有标准,只要它们存在。对于密码散列,适用的标准是Modular Crypt Format。如果您正在设计一个没有强互操作性要求的新方案,那么您也可以使用Password Hashing Format

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-17
    • 2023-03-14
    • 2012-01-08
    • 2011-12-06
    • 2016-09-17
    • 1970-01-01
    • 1970-01-01
    • 2013-11-21
    相关资源
    最近更新 更多