天道酬勤,学无止境

在 C# 中存储使用 MD5CryptoServiceProvider 散列的密码是否安全?(Is it safe to store passwords hashed with MD5CryptoServiceProvider in C#?)

问题

我们将散列密码存储在数据库表中。

我们使用 MD5CryptoServiceProvider 为每个密码添加一个随机盐值和哈希值。

这安全吗? 我听说 MD5 已“损坏”。

如果没有,您能否推荐一种替代的哈希方法来使用(特定的 .NET 框架类)?

回答1

我认为此时 SHA256、SHA512 更安全:)

见维基

回答2

散列函数的安全性主要来自其输出(消息摘要)的长度:摘要越长,抗碰撞性越大。 生日悖论告诉我们,平均而言,您希望从摘要大小的平方根的工作函数中找到碰撞:换句话说,给定 128 位摘要,攻击者希望在 2^ 64 次试验。

MD5 多年来一直受到密码学界的反对,因为它只有 128 位的摘要,而且还有一些有趣的密码分析结果可能会有效地降低其强度。 SHA1(160 位摘要)一直是首选的替代方案,但即便如此,对于动机良好的对手来说,它似乎还不够长,而且研究界也有一些有趣的结果。 SHA-2 系列(输出大小从 224 位到 512 位)是当前广泛使用的首选散列函数。 NIST 组织了一场积极的研究竞赛,以寻找 SHA-2 的继任者,但我们要到 2012 年左右才会有新标准。

现在,在存储密码的特定情况下,我注意到您使用的是盐。 这是强烈推荐的做法; 如果没有盐,你很容易受到彩虹表攻击。 我相信这让您只需要考虑蛮力攻击; 这就是 keylength.com 的用武之地。它汇集了来自整个加密社区的密钥和摘要大小的建议,并为各种算法提供了预期的安全时间表,同时考虑了当前的计算能力并考虑了摩尔定律。 考虑一下您要保护的资产类型以及密码需要多长时间才能保持安全(例如,您是否有强制执行的密码更改策略?),这几乎可以回答您需要的摘要大小问题。

当然,如果您的用户使用易于猜测的密码,那么世界上最好的密码存储也无济于事。 您是否为您的用户提供强密码提示? 您是否考虑过使用密码强度计或类似工具?

回答3

不,您不应该使用 MD5。 但是您也不应该使用任何通用哈希函数的单轮,无论它在密码学上多么安全! 不是 MD5,不是 SHA-1,不是 SHA-2,不是 SHA-3。

为什么? 因为通用哈希函数被设计得很快。 而快速正是您在密码哈希中想要的。 快速意味着当坏人获得您的数据库时,他们可以在合理的时间内对其进行普通的旧字典攻击。

你需要的是。 变慢的最简单方法是迭代快速哈希函数数千次——这就是用于在类 UNIX 系统上存储密码的基于 MD5 和 SHA-1 的密码方案所做的(它不仅仅是一轮 MD5 或 SHA-1 )。 另一种方法是使用设计为慢的加密原语 - 这就是“bcrypt”密码方案所做的。

这篇 Matasano 文章,您需要了解的关于安全密码方案的内容,对这个主题有一些很好的阅读。

回答4

使用 salt MD5 比不使用更安全,但最好使用其中一种 SHA 哈希,例如 SHA256Managed。

回答5

存储散列密码更好,因为它隐藏了 DBA 窥探的密码。

此外,是的,MD5 已损坏,但至今仍在使用。 如果您担心 MD5,请使用 SHA-1(此处为 MSDN 链接)。 它是一种散列算法,就像 MD5 一样,但更强大。 您可以拥有最多 512 位的 SHA-1 散列。

这是在 VB.NET (http://www.obviex.com/samples/hash.aspx) 上完成的示例。

这是美国国土安全部说明为什么人们应该远离 MD5 (http://www.kb.cert.org/vuls/id/836068)。 总结,它“密码学上已损坏”

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 使用MD5或sha-256 C#散列密码(Hashing passwords with MD5 or sha-256 C#)
    问题 我正在为应用程序编写注册表,但是在使用C#时仍然遇到问题。 我正在寻找加密/哈希密码到md5或sha-256,最好是sha-256。 有什么好的例子吗? 我希望它能够从“字符串密码”中获取信息; 然后对其进行哈希处理并存储在变量“ string hPassword;”中。 有任何想法吗? 回答1 不要使用简单的哈希,甚至不要使用盐腌的哈希。 使用某种密钥加强技术,例如bcrypt(在此使用.NET实现)或PBKDF2(在内置的实现中)。 这是使用PBKDF2的示例。 要从您的密码生成密钥... string password = GetPasswordFromUserInput(); // specify that we want to randomly generate a 20-byte salt using (var deriveBytes = new Rfc2898DeriveBytes(password, 20)) { byte[] salt = deriveBytes.Salt; byte[] key = deriveBytes.GetBytes(20); // derive a 20-byte key // save salt and key to database } 然后测试密码是否有效... string password =
  • 在 cookie 中存储(散列)密码是否安全?(Is it safe to store (hashed) passwords in a cookie?)
    问题 我读过一些关于 SO(例如这里)的文章和问题,这些文章和问题说你不应该将用户的密码存储在 cookie 中。 如果密码被加盐和散列,为什么这不安全? 特别是,为什么它不如使用会话(通常建议的替代方法)安全? 如果用户想保持登录状态,那么这个新 cookie(带有会话 ID/哈希)肯定与带有用户密码的 cookie 一样安全? 如果 cookie 以某种方式被“窃取”,攻击者可以以相同的方式以用户身份登录。 编辑:问题的主要症结是关于用户保持登录状态的部分,即通过“还记得我吗?” 复选框。 在这种情况下,肯定只有一个会话吗? 回答1 会话通常在某种程度上锁定到 IP 地址,从而在某种程度上防止会话被盗。 除此之外,会话 ID 不包含任何个人信息; 你的密码,即使是加盐和散列的也是如此。 加密和散列的密码可以重复使用; 会话 ID 不能。 一旦会话结束,就结束了,您需要一个新的会话 ID 才能再次模拟用户。 回答2 通过将散列密码 + salt 放入 cookie,您: 打开一个无限的蛮力向量允许任何人复制和使用 cookie(它总是允许访问;而会话会持续一段时间)。 如果它变得相关,则更难更改散列方案 此外,您通常需要存储其他内容以识别用户(例如他们的用户 ID,因此您可以查找他们的密码并进行匹配)。 这可能会导致其他晦涩的问题。 所以你最好只使用 session id 方法。
  • 在数据库中存储密码的最佳方法(Best way to store password in database [closed])
    问题 从目前的情况来看,这个问题不适合我们的问答形式。 我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意测验或进一步的讨论。 如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 8年前关闭。 我正在一个必须进行身份验证(用户名和密码)的项目中 它还连接到数据库,所以我想我将在其中存储用户名和密码。 但是,在数据库上的表中仅具有文本字段的密码似乎不是一个好主意。 我正在使用C#并连接到2008 Express服务器。 谁能(以尽可能多的示例)建议存储这种类型的数据的最佳方法是什么? 附言:如果可以提供充分的理由,我不希望此信息不存储在数据库中 回答1 您将密码存储在纯文本字段中是一个可怕的主意,这是正确的。 但是,就位置而言,在大多数情况下(您真的会想到(我真的没有想到任何反例)),在数据库中存储密码表示是正确的做法。 通过表示,我的意思是您想使用盐(每个用户应该有所不同)和安全的1向算法对密码进行散列并存储该密码,从而丢弃原始密码。 然后,当您要验证密码时,可以对值进行哈希处理(使用相同的哈希算法和盐),并将其与数据库中的哈希值进行比较。 因此,尽管您正在考虑这是一件好事,而且这是一个好问题,但这实际上是这些问题的重复(至少): 如何最好地存储用户信息以及用户登录名和密码存储数据库密码的最佳做法给密码加盐:最佳做法?
  • 如何升级密码存储方案(更改散列算法)(How to upgrade a password storage scheme (change hashing-algorithm))
    问题 我被要求对内部网站进行一些更改/更新; 让它成为他们所说的“未来证明”。 我们发现密码是使用 MD5 算法散列的。 (该系统自 2001 年以来一直存在,因此当时已经足够了)。 我们现在想将散列算法升级到更强的算法(BCrypt-hash 或 SHA-256)。 我们显然不知道纯文本密码,因此不能为用户群创建新密码*) 。 所以,我的问题是: 在无法访问明文密码的情况下更改散列算法的可接受方法是什么? 最好的解决方案是完全“幕后”的解决方案。 *) 我们尝试了; 试图说服他们,我们使用了“密码年龄”的论点,试图用咖啡贿赂他们,试图用蛋糕贿赂他们等等。但这不是一种选择。 更新我希望有某种自动解决方案来解决这个问题,但显然除了“等待用户登录,然后转换”之外没有其他选择。 好吧,至少现在我没有其他可用的解决方案。 回答1 首先,向数据库添加一个字段,以识别密码是使用 MD5 还是新算法。 对于仍然使用 MD5 的所有密码: -- 在登录过程中,您验证用户输入的密码:将用户提交的密码临时存储在内存中(这里没有安全问题,因为它已经在内存中的某处)并执行通常的 MD5 哈希并与存储的哈希进行比较; -- 如果给出了正确的密码(与现有哈希匹配),则通过新算法运行临时存储的密码,存储该值,更新新字段以标识此密码已更新为新算法。 (当然,您只需将新算法用于任何新用户/新密码。) 回答2
  • 在表单身份验证 cookie 中存储密码 - ASP.NET 和 WCF 调用(Storing password in forms authentication cookie - ASP.NET and WCF calls)
    问题 为了我的网络应用程序安全,我使用 FormsAuthentication/MembershipProvider 和非持久性 cookie。 我的应用程序与一些 Web 服务交互,这些服务也使用 Membership 提供程序。 用户密码在数据库中散列。 问题是登录到应用程序的人需要在每次加载页面时使用他的用户名和密码对 Web 服务进行身份验证。 但是一旦用户登录了他的密码,就无法检索,因为它是散列的。 我想知道是否可以将密码安全地存储在身份验证 cookie 中,以便用户可以通过 Web 服务进行身份验证。 或者更好的主意! 编辑我喜欢下面的 JOHNS IDEA,但有 4 条关于我想在走这条路线之前解决的机制的评论...... 回答1 我同意@John 的回答,即使用一次性令牌比存储凭据更好。 对于令牌,您可以生成一些随机 GUID 并将其存储在数据库中。 作为不需要在 ASP.NET 应用程序和 WCF 服务之间进行协调的替代方法,您可以将签名文档作为令牌发送。 创建带有签名时间、用户名和签名者姓名的 XML 或 JSON 文档(ASP.NET 应用程序)。 生成上述文档的哈希值。 使用非对称加密(使用私钥)对哈希进行签名。 WCF 要做的就是验证散列和签名。 所以这不涉及访问相同的数据库。 使用签名时间,您可以在固定时间内使令牌过期。 编辑:这个想法基于公钥密码­
  • 从未加盐到加盐的 MD5 密码(Going from unsalted to salted MD5 passwords)
    问题 我有一个正在流行的 LAMP (PHP) 网站。 我通过将用户密码存储为 md5 哈希来确保安全。 但我现在看到这并不安全; 我应该对 md5 散列加盐 - 因为目前可以使用彩虹表解码未加盐的 md5 散列。 我能做什么? 我不想让每个人都输入新密码。 回答1 您可以执行“两步散列”而不是一步创建散列。 您可以将每个密码哈希附加到用户名,然后再次对其进行哈希处理。 这将创建一个不可解密的散列,其中包含独特的信息。 通常的腌制过程是 盐+密码 -> 哈希 您可以执行以下操作:PWD -> Hash -> UserID+Hash -> Hash (请注意,UserID 仅被选中,因此每个双散列的唯一盐存在......随意使您的盐更复杂) 回答2 你可以在飞行中给它们加盐。 添加一段代码,以便当有人登录时,它会执行正常的过程(计算密码的 MD5 总和并根据存储的散列进行检查),如果成功,则从清除中重新计算散列的加盐版本 -他们输入的文本密码,并将其存储在密码文件中。 唯一的问题是您需要为每个 MD5 是否加盐添加一个指示符,因为您将在一段时间内混合使用两者。 或者,为了稍微降低安全性,您可以检查每个加盐和不加盐的密码,如果有一个命中,则接受登录。 当然,如果您检测到它是未加盐的,那么您就可以升级了。 回答3 答案很简单,确保在新的散列系统上保留记录或某种标志,其中用户具有密码
  • 用散列存储盐可以吗?(Is it okay to store salts with hashes?)
    问题 我的理解是,salt 并不打算保密,它只是为了与任何集中式标准不同,因此您无法开发彩虹表或类似的攻击来破坏使用该算法的所有哈希,因为盐会破坏彩虹桌。 我的理解可能不完全正确,如果我错了,请纠正我。 在广泛使用的开源软件中,salt 将广为人知,这让您容易受到攻击,因为现在他们可以简单地攻击您的散列的加盐版本并创建包含盐数据的彩虹表。 在我看来,有两种选择可以解决这个问题。 第一种是在软件的每个新版本中更改盐,但这并不好,因为软件的新版本将不再能够针对旧密码哈希进行测试。 我想到的第二个解决方案是为每个密码存储一个盐; 换句话说,每个密码都有不同的盐。 缺点是盐必须以某种方式与密码哈希相关联,可能只是将它们贴在数据库中的密码旁边。 甚至可以使用用户名(但可能不是,可能用户名太短了)。 我的问题是,这可以接受吗? 直接用它散列的密码存储盐是否有任何额外的风险? 在我看来,在源代码中存储盐并没有什么不同,因此通过将盐与密码一起存储不会造成安全损失。 免责声明:我没有将它用于任何现实生活中的安全系统。 事实上,我从未设计过任何类型的密码系统。 我只是让自己模糊地了解安全问题。 回答1 更新:使用合适的库,例如 Python 的 passlib。 它们负责生成每个密码的盐,并使用适当的散列算法(仅使用诸如 SHA1 之类的加密散列是不够的;您必须以一种使其反转速度非常慢的方式应用它
  • 是否值得在客户端哈希密码(Is it worth hashing passwords on the client side)
    问题 当我想放置一个登录系统时,我总是将给定密码的MD5与服务器端的users表中的值进行比较。 但是,我的一个朋友告诉我,网络软件可能会嗅到“清除”密码。 所以我的问题是:在客户端哈希密码是否是一个好主意? 它比在服务器端对其进行哈希处理更好吗? 回答1 基本上,您的朋友是对的。 但是,简单地散列在客户端的密码是不是提交它以纯文本的服务器才刚刚好。 可以侦听您的纯文本密码的人当然也可以侦听哈希密码,并使用这些捕获的哈希值来对您的服务器进行身份验证。 为此,通常通过允许客户端选择一堆随机位(随密码一起散列),以确保更可靠的身份验证协议通常无法跳过,从而确保这种重播攻击不起作用。 ,并且还明确地提交给服务器。 在服务器上: 产生一些随机将这些位(以明文形式)发送给客户端 在客户端上: 产生一些随机位连接密码,服务器的随机位和客户端的随机位生成上面的哈希提交随机位(以明文形式)并哈希到服务器 由于服务器知道自己的随机信息以及客户端的随机位(以明文形式获取它们),因此它可以执行基本相同的转换。 该协议可确保,只要双方都每次都产生不同的“噪声位”,那么在此对话中收听的任何人都无法稍后使用该信息来对记录的信息进行错误的身份验证(除非使用了非常弱的算法...),进行了握手。 编辑所有这些都是容易出错和乏味的,并且很难正确处理(阅读:安全)。 如果可能的话
  • 是否可以解密MD5散列?(Is it possible to decrypt MD5 hashes?)
    问题 有人告诉我,他看到过以下软件系统: 从其他系统检索MD5加密的密码; 解密加密的密码并使用系统自己的算法将密码存储在系统的数据库中。 那可能吗? 我认为解密MD5散列是不可能/不可行的。 我知道有MD5词典,但是有实际的解密算法吗? 回答1 不能。MD5不是加密(尽管它可以用作某些加密算法的一部分),它是一种单向哈希函数。 实际上,许多原始数据在转换过程中实际上是“丢失”的。 考虑一下:MD5始终为128位长。 这意味着有2 128个可能的MD5哈希。 这是一个相当大的数字,但绝对是有限的。 但是,给定散列函数有无限数量的可能输入(其中大多数包含超过128位,或仅16个字节)。 因此,对于散列为相同值的数据来说,实际上存在无限数量的可能性。 使哈希变得有趣的是,很难找到两个散列为相同值的数据,并且偶然发生的几率几乎为零。 一个(非常不安全)哈希函数的简单示例(这说明了它是单向的),将数据的所有位都当作一个大数来对待。 接下来,使用一些大的(可能是素数) n执行整数除法,然后取余数(请参阅:模数)。 您将剩下0到n之间的某个数字。 如果要使用完全相同的字符串再次(在任何时间,在任何计算机上,任何地方)再次执行相同的计算,它将得出相同的值。 然而,有没有办法找出原来的值,因为有一些有确切的数字剩余,当除以n无限多的。 也就是说,已经发现MD5有一些弱点
  • 是否可以解密MD5哈希?(Is it possible to decrypt MD5 hashes?)
    问题 有人告诉我,他看到过以下软件系统: 从其他系统检索MD5加密的密码; 解密加密的密码并使用系统自己的算法将密码存储在系统的数据库中。 那可能吗? 我认为解密MD5散列是不可能/不可行的。 我知道有MD5词典,但是有实际的解密算法吗? 回答1 不能。MD5不是加密(尽管它可以用作某些加密算法的一部分),它是一种单向哈希函数。 实际上,许多原始数据在转换过程中实际上是“丢失”的。 考虑一下:MD5始终为128位长。 这意味着有2 128个可能的MD5哈希。 这是一个相当大的数字,但绝对是有限的。 但是,给定散列函数有无限数量的可能输入(其中大多数包含超过128位,或仅16个字节)。 因此,对于散列为相同值的数据来说,实际上存在无限数量的可能性。 使哈希变得有趣的是,很难找到两个散列为相同值的数据,并且偶然发生的几率几乎为零。 一个(非常不安全)哈希函数的简单示例(这说明了它是单向的),将数据的所有位都当作一个大数来对待。 接下来,使用一些大的(可能是素数) n执行整数除法,然后取余数(请参阅:模数)。 您将剩下0到n之间的某个数字。 如果要使用完全相同的字符串再次(在任何时间,在任何计算机上,任何地方)再次执行相同的计算,它将得出相同的值。 然而,有没有办法找出原来的值,因为有一些有确切的数字剩余,当除以n无限多的。 也就是说,已经发现MD5有一些弱点
  • 密码,哈希和密码问题,总算是菜鸟吗?(Crypto, hashes and password questions, total noob?)
    问题 我已经阅读了几篇有关该主题的stackoverflow帖子,尤其是关于这一主题的文章: 保护PHP密码的哈希和盐值 但我还有几个问题,需要澄清,请告诉我以下陈述是否正确,并解释您的意见: 如果有人可以访问您的数据库/数据,那么他们仍然必须弄清楚您的哈希算法,并且您的数据仍将在一定程度上取决于您的算法? 他们所拥有的只是哈希和盐。 如果某人可以访问您的数据库/数据和源代码,那么无论您做什么,似乎都可以对您的哈希算法进行反向工程,那么您唯一拥有的就是算法的复杂性和耗时性是? 似乎最薄弱的一环是:您自己的系统有多安全,谁可以访问它? Lasse V. Karlsen ...提出了一个很好的建议,如果您的数据受到威胁,那么游戏就结束了...我的后续问题是:这些哈希试图防御哪些类型的攻击? 我已经阅读了有关彩虹表和字典攻击(蛮力攻击)的信息,但是如何管理这些攻击呢? 回答1 您的问题是关于使用密码作为身份验证机制,以及如何使用哈希将这些密码安全地存储在数据库中。 您可能已经知道目标是能够在不存储这些密码的情况下验证密码,但我会清除数据库中的文本。 在这种情况下,让我尝试回答您的每个问题: 如果有人可以访问您的数据库/数据,那么他们仍然必须弄清楚您的哈希算法,并且您的数据仍将在一定程度上取决于您的算法? 他们所拥有的只是哈希和盐。 哈希密码的基本思想是,攻击者了解哈希算法
  • 当密码存储为哈希值时检索密码(Retrieving password when the password stored as a hash value)
    问题 如果密码存储为哈希值,用户可以要求将密码发送给自己吗? 有什么方法可以将具有适当信息(以及您需要什么信息)的哈希值转换为明文值? 如果用户在两个站点上存储的密码哈希值相同,那么两个站点的密码是否相同? 回答1 如果仅存储密码的哈希,则否。 ...而且无论如何,您只应存储正确加密的密码哈希值。 密码重置机制是正确的选择。 回答2 散列的密码通常无法检索(这取决于散列函数,无法检索安全散列)。 如果它们在两个站点上具有相同的哈希,则它们可以具有相同的密码,这取决于站点所使用的哈希盐,什么方法等。 如果您的密码安全地存储在良好的哈希系统中,则提供程序永远都不能通过电子邮件将密码发送给您,如果忘记了密码,则必须重设密码。 回答3 简而言之,不。 使用大多数散列算法,您可以将多个输入具有相同的输出。 通常最好提供一个密码重置选项。 回答4 有不同类型的哈希算法。 有些比其他的更安全。 MD5是一种流行但不安全的产品。 SHA系列是另一套更安全的算法。 根据定义,哈希是一种单向函数。 它不能逆转。 http://en.wikipedia.org/wiki/Sha-1 回答5 如果有一种简单的方法来恢复明文密码,则首先对哈希进行哈希运算就没有意义了。 到那时,您最好只使用base64或ROT13。 (不要那样做!) 如其他人所述,请使用其他密码恢复方法。
  • 盐,密码和安全性(Salt, passwords and security)
    问题 我已经阅读了许多有关此的问题,但是许多答案彼此矛盾,或者我听不懂。 您应该始终将密码存储为哈希,而不是纯文本。 但是您应该将盐(每个用户唯一)存储在数据库中哈希密码+盐旁边。 在我看来,这似乎不太聪明,因为有人无法访问数据库,寻找说出名为Admin的帐户或其他名称,然后从中找出密码吗? 回答1 很多人说“停止彩虹表”而没有解释彩虹表的作用或阻止彩虹表的原因。 Rainbow表是一种聪明的方法,可以预先计算大量的哈希并将其存储在比天真的需要的内存少的内存中,您可以使用它们非常快速地反转哈希。 诸如hash = md5(password)和hash = sha1(password)类的裸函数表是常见的。 但是,可以为任何哈希函数生成它们,可以将其描述为output = f(input) 。 如果对所有用户密码都使用站点范围内的盐,例如hash = md5(salt+password) ,则可以构造函数f , f(password) = md5(salt+password) 。 因此,您可以为此功能生成彩虹表,这将花费很长时间,但是随后您可以非常快速地破解数据库中的每个密码。 如果每个密码的盐值都不相同,则无法生成将破解数据库中所有密码的彩虹表。 您可以为每个用户生成一个新文件,但这将毫无意义-天真的暴力破解不会变慢。 因此,为每个用户使用单独的盐可以阻止彩虹表攻击。
  • 在客户端哈希密码是否有意义?(Does it make security sense to hash password on client end)
    问题 如果要在跨行发送用户密码之前对其进行哈希处理,然后将其以纯文本格式保留在内存中,这是否可以提高应用程序的安全性? 我认为这可以通过保护客户端内存中存储的数据来缓解一小部分漏洞。 但是,实际上,如果我们担心有人会读取客户的记忆,则可能存在我们无法解决的更大问题。 在客户端端进行哈希运算有些不对劲。 客户端上的密码哈希是一种常见的做法吗? 这样做还有其他优点或缺点吗? 编辑:给定的通信通道是安全的(SSL)。 在什么条件下使用这种方法是可以接受的,也是值得的。 我之所以这么问,是因为“安全专家”建议我在某些应用程序功能中使用这种方案。 回答1 不。 当客户发送东西时,无论是P还是H(P)还是H(H(P))任何拦截此东西的人都可以简单地重新发送完全相同的东西,从而使像这样的任何功能等同于直接使用密码。 这就是为什么您应该使用随机数。 服务器可以发出一些随机垃圾k ,客户端将计算H(P,k)并将其发送到服务器。 HMAC是此方法的流行实现。 如果服务器永不两次接受同一随机数,则可以防止重放攻击。 回答2 在您描述的场景中,哈希值与来自安全POV的密码相同:如果我拦截了哈希值,则不需要知道密码,只需将所拦截的哈希值发送给服务器即可。 身份验证协议要花一些时间来避免此问题。 安全性很难,最好不要选择和实施易于理解的协议,而不要自己动手编写协议。 如果您的流量是通过SSL传输的
  • 散列机制真的安全吗?(is hashing mechanism really secure?)
    问题 好吧,我一直看到(和跟随)人们说使用散列机制在数据库中存储密码。 我真的很担心它安全吗? 让我们举个例子。 假设我是黑客,我得到了你的数据库名称、ID 和密码。 现在我可以完全访问您的数据库。 人们所说的密码应该被散列,因为如果有人入侵,黑客就可以看到它们。 所以如果我以select id, password FROM userDetails运行查询select id, password FROM userDetails我将获得如下数据 选项 1:没有哈希 ++++++++++++++++++++++++++++ + id + password + ++++++++++++++++++++++++++++ + id01 + password01 + + id02 + password02 + ++++++++++++++++++++++++++++ 选项 2:使用哈希 ++++++++++++++++++++++++++++ + id + password + ++++++++++++++++++++++++++++ + id01 + hasValue01 + + id02 + hasValue02 + ++++++++++++++++++++++++++++ 好吧,我仍然要说,散列是不安全的。 为什么我下面会用Java代码告诉你。 PreparedStatement pst
  • 在发送给服务器端之前,我应该先对密码进行哈希处理吗?(Should I hash the password before sending it to the server side?)
    问题 我注意到大多数站点都通过HTTPS以纯文本形式将密码发送到服务器。 如果我不是将密码的哈希值发送到服务器,那有什么好处吗? 会更安全吗? 回答1 这是一个古老的问题,但我感到有必要就这一重要问题发表意见。 这里有太多错误信息 OP从未提及过通过HTTP明确发送密码-仅HTTPS,但是出于某种原因,许多人似乎正在响应通过HTTP发送密码的问题。 说: 我认为密码绝不应该以纯文本形式保留(更不用说传输了)。 这意味着不保存在磁盘上,甚至不保存在内存中。 在此做出回应的人们似乎认为HTTPS是灵丹妙药,但事实并非如此。 但是,它当然可以极大地帮助您,并且应该在任何经过​​身份验证的会话中使用。 确实不需要知道原始密码是什么。 所需要的只是基于用户选择的原始文本生成(并可靠地重新生成)身份验证“密钥”的可靠方法。 在理想的世界中,此文本应立即通过使用不可逆的盐对其进行哈希处理来生成“密钥”。 该盐对于所生成的用户凭证应该是唯一的。 此“密钥”将是您的系统用作密码的密钥。 这样,如果您的系统将来会受到威胁,这些凭据将仅对您自己的组织有用,而在其他地方,用户会变得懒惰并使用相同的密码。 所以我们有一把钥匙。 现在,我们需要清除客户端设备上密码的任何痕迹。 接下来,我们需要将该密钥传递给您的系统。 您切勿“明文”传送密钥或密码。 甚至没有通过HTTPS。 HTTPS是不可渗透的。 实际上
  • 散列密码和加密密码之间的区别(Difference between Hashing a Password and Encrypting it)
    问题 当前对该问题的最高投票指出: 另一个与安全性无关的安全性问题虽然完整,但却完全无法解决哈希散列密码和加密密码之间的区别。 最常见于程序员试图提供不安全的“提醒我密码”功能的代码中。 到底有什么区别? 我总是给人以哈希是一种加密形式的印象。 海报所指的不安全功能是什么? 回答1 散列是一种单向函数(嗯,是映射)。 这是不可逆的,您应用了安全哈希算法,就无法取回原始字符串。 您最多可以做的就是生成所谓的“冲突”,即找到提供相同哈希值的不同字符串。 加密安全的哈希算法旨在防止冲突的发生。 您可以使用彩虹表来攻击安全哈希,可以在存储哈希之前对哈希应用盐来抵消它。 加密是一种适当的(双向)功能。 这是可逆的,如果您拥有密钥,则可以解密损坏的字符串以获取原始字符串。 它所指的不安全功能是,如果您对密码进行加密,则应用程序会将密钥存储在某个位置,并且可以访问数据库(和/或代码)的攻击者可以通过同时获取密钥和加密文本来获取原始密码,而使用散列是不可能的。 人们通常说,如果破解者拥有您的数据库或代码,那么他不需要密码,因此区别不大。 这是幼稚的,因为您仍然有责任保护用户的密码,这主要是因为大多数用户确实一次又一次地使用相同的密码,从而使密码泄露的风险更大。 回答2 散列是一个单向函数,这意味着一旦你散列密码是很难摆脱的哈希原来的密码后面。 加密是一种双向功能,从加密文本取回原始文本要容易得多。
  • 插入数据库时​​散列加密密码(Hash encrypting password when inserting into database)
    问题 我正在为学校申请,在将密码插入我的用户数据库时需要帮助加密密码。我正在使用 c# 编程语言进行编程,并且正在使用 MS server 2008 R2 来操作我的数据库。 我正在考虑进行 HASH 加密,如果有人帮助我,我会很高兴。 这是我将数据插入数据库的代码: using (SqlConnection con = new SqlConnection("Data Source=HRC0;Initial Catalog=users;Integrated Security=True")) //MLHIDE using (SqlCommand sc = new SqlCommand("if NOT exists (select * from users where UserName = @username) insert into users (userName, password) values(@userName, @password)", con)) { con.Open(); sc.Parameters.AddWithValue("@username", korisnik.Text); sc.Parameters.AddWithValue("@password", pass.Text); int o = sc.ExecuteNonQuery(); if (o == -1)
  • 每个 Web 开发人员都应该了解哪些有关加密的信息?(What should every web developer know about encryption?)
    问题 我刚刚获得了 PHP5 演出。 我不会处理涉及超级敏感数据的应用程序部分,但我仍然对安全性和加密方法知之甚少。 我只知道非常基础的知识(不要以明文形式存储密码,不允许用户使用发布数据运行代码等)。 我需要知道什么来保证我的应用程序安全,我可以从哪里学习? 回答1 了解散列和加密之间的区别。 加密通常是字符串的双向解释。 我可以加密我的密码,然后再次将其解密为明文。 散列背后的想法是它们成为一种单向“加密”。 在我的网站上,我将密码存储为哈希值。 每当用户登录时,我都会重新散列他们提供的密码,对照存储在数据库中的散列对其进行测试,并批准它们是否匹配。 如果他们忘记密码,我无法向他们发送密码,因为(通常)我无法知道。两个不同的字符串可以转换为相同的哈希值,这使得(通常)无法找出原始字符串是什么。 这是一个有助于深入了解和辨别何时使用加密与散列的问题。 回答2 知道不要编写自己的加密功能。 一个现有的、受信任的图书馆是最好的方式去尽可能。 避免使用落后于许多成功的程序员和用户时间的酷炫前沿技术。 知道不要相信你选择的功能,直到你自己彻底测试过它,第一人称。 跟上新的发展,这些发展可能会使您选择的功能在一夜之间过时。 要知道,仅仅因为您使用了当今最好的加密技术,如果您将密钥留在表中(例如,明文不在缓存中或存储在同一数据库的另一个表中,私钥不留在露天) 回答3
  • 对加密数据进行全文搜索(Full text search on encrypted data)
    问题 假设我有一个存储加密文本的服务器(端到端:服务器永远不会看到纯文本)。 我希望能够对该文本进行全文搜索。 我知道这很棘手,但我的想法是使用传统的全文设计(“列表”和“匹配”表,其中存储单词并与内容表中的 id 匹配)。 当用户提交加密文本时,他们还会发送单词和相应匹配项的加盐 MD5。 使用的盐对于每个用户都是唯一的,并且可以从他们的密码中恢复。 (简而言之:唯一的区别是“列表”表将包含散列词) 现在,这个系统有多脆弱? 请注意,我说的是“多么脆弱”而不是“多么安全”,因为我承认它不可能完全安全。 我确实理解功能(全文搜索)和安全性(从词索引中披露一些信息)之间的权衡。 例如,我知道能够获取列表和匹配表的攻击者可以获得有关原始加密文本的信息,并且可能能够通过统计分析破译一些单词(但是,作为每个用户唯一的盐,这需要对每个用户重复)。 这种威胁会有多严重? 还会有其他严重的威胁吗? 免责声明我正在尝试构建(并在密码学家的帮助下进行实际实施;现在我只是想了解这是否可行)是一种消费级产品,它将处理机密但并非完全机密的数据. 我的目标只是提供足够安全的东西,以便攻击者更容易尝试窃取用户的密码(例如入侵客户 - 他们最终是消费者),而不是花费大量时间和计算能力尝试强制执行索引或运行复杂的统计分析。 回复@Matthew 的评论 (可能与其他任何人的回答有关) 正如您所指出的