2

由于对安全感兴趣,特别是散列,我想出了一个既可以帮助破坏密码安全。

“破坏”散列的主要方法是对其进行暴力强制。

因此,虽然有时很难说,但大多数时候,你可以猜测或至少列出你的哈希可能是几种不同的哈希算法,并首先尝试最可能的算法。

这是我的想法:生成一个散列,比如说MD5,然后,例如,在开始或结束处添加100个随机字符,然后将这个新字符串存储在数据库中。

如果数据库被破坏,这可能使我们几乎无法猜测它是什么类型的散列。

现在,您可能会认为这实际上只是一种较弱的加密方式,但是这是一个陷阱-添加的字符数为不同的针对每个用户!

用户A添加了98,但用户B添加了82!

这取决于两件事,然而,散列算法是保密的,添加是在客户端完成的,并备份到另一个客户端分离服务器。

有专家能告诉我这是个好主意还是坏的

如果它不好,请提供一些理由,记住,如果我错过了一个巨大的缺陷,请不要评判我-我不是专家-只是一个应用程序和数据库编码器和安全性狂热爱好者。

12
  • 如果添加随机字符是在客户端完成的,那么如何将此随机信息分发给所有客户端?如果有人试图使用公共信息亭,它如何知道用户的随机信息?
    ——巴尔马
    5月15日14:30
  • 19
    对于“我刚刚提出的密码存储或加密的想法好吗?”,答案是“不,使用行业标准的密码散列或加密,它是由专家开发的”。永远不要自己滚。 5月15日16:02
  • 14
    “散列,比如MD5”-我知道这只是一个例子,但无论如何我都要提到它:永远不要使用普通散列来存储密码。使用慢速迭代的密码散列和salt。好的专用密码哈希算法包括(从好到坏):argon2、scrypt、bcrypt、PBKDF2。并避免使用MD5(和SHA1)。 5月15日17:16
  • 2
    不安全不是安全。 5月15日23:09
  • 5
    所以,显而易见的问题是,如果你在预散列的密码中添加一些随机内容,你如何重建随机元素以验证密码是否正确?如果答案是您将随机内容与散列密码一起存储在数据库中,那么您基本上只需要重新激活盐渍。。。 5月16日5:27

4个答案4

重置为默认值
57

你最近问过“默默无闻的安全”。就是这样。这是一个非常复杂的过程,一旦知道就会失败。

如果哈希数据库从一个服务器泄漏,为什么你相信另一个数据库没有泄漏?与使用带有salt的强散列算法(而不是MD5)的既定过程相比,这几乎没有什么好处。

另一个问题是您正在散列密码客户端,这意味着散列成为密码。一旦数据库泄漏,就不需要破坏散列,只需将该散列传递给服务器即可。您不需要知道原始明文密码是什么。因此,所有这些复杂性都是毫无意义的。

请查看“模糊安全性”、Kerckhoffs原则(在您的另一个问题中提到过)和客户端密码散列。

7
  • 谢谢你指出这些缺陷。是的,看起来这只是制造了比实际解决更多的问题! 5月15日7:07
  • 您可能需要扩展答案:“散列算法是保密的”-这违反了克尔霍夫原理。 5月15日8:03
  • 1
    @mentalllurg我将使用更广泛的应用程序。在OP的设计中,试图保密的不仅仅是算法类型。柯克霍夫斯的更广泛应用表明,整个设计应该在已知的情况下继续存在,而且这个设计有很多秘密。
    ——施罗德
    5月15日8:09
  • 散列服务器端是标准实践,他们没有指定在存储之前不存在服务器端散列。客户端哈希不排除服务器端哈希。
    ——n-l-i型
    5月16日6:42
  • @JamesT有时,由于惯性、便利性或其他与实用性相关的原因,而非技术优化,现状依然存在。提问没有害处,你可能会得到这样的答案:“理论上可能更好,但这就是为什么不可行。”
    ——巴尔马
    5月16日15:00
19

撇开一些技术实现问题(您如何生成“随机”字符,您的服务器如何通信以计算出需要从每一面剥离多少字符等)不谈,这直接违反了科尔乔夫原理,其中规定:

密码系统应该是安全的,即使除了密钥之外,系统的所有信息都是公开的。

这意味着,如果攻击者能够访问您的源代码,那么这种额外的安全性就会突然消失。

攻击者还可以相对容易地确定该方案,他们所需要的只是一个已经知道密码的帐户的填充哈希,并且他们很快就会发现其中包含md5($password)然后有一些额外的填充。因为他们不知道真正散列的位置,所以破解起来会有点困难,但仍比破解bcrypt或Argon2id等正确的密码存储算法容易几个数量级。

如果要防止攻击者仅通过数据库访问破解哈希,可以使用以下技术胡椒或加密数据库中的密码散列。

但如果您使用的是带有合理参数的Argon2id算法,则散列已经非常很难破解——所以你最好做这样的事情,而不是试图围绕MD5这样的弱散列算法构建自己的密码存储系统。

作为一般经验法则,任何时候你想做自定义加密都可能是个坏主意,因为加密真的很难以获得正确的结果。

0
4

如果你在客户端进行散列和填充,那么你怎么能对算法保密呢。考虑到你试图混淆你的代码,但它仍然可以很容易地被真正有动机的人消除。所以在这一点上是失败的。

7
  • 感谢@schroeder的指出。我现在明白了问题的所在。我仍会坚持我的第二点,即作为一名攻击者,我手中掌握着散列算法和填充算法(它可能会被混淆,但它就在客户端的某个地方),这减少了我破解数据库和计算散列的工作量。现在,作为一名攻击者,我只需要观察图案并找出垫子的位置。完成后,我可以像往常一样执行暴力攻击,并尝试以其他人的身份登录。 5月16日10:16
  • 此外,服务器将用于验证哈希的方法也非常不清楚,我假设两个服务器将在它们之间进行通信,并使用一些公共id检索填充。我假设服务器将生成id并将带有id的填充存储在单独的服务器上,如果我错了,请纠正我。 5月16日10:20
  • 这假定攻击者有权访问客户端。从评论和设计来看,我认为OP没有攻击者拥有客户端和服务器的威胁模型。
    ——施罗德
    5月16日10:47
  • 我想说的是,攻击者可以自己冒充客户端,通过尝试不同的密码并找出模式来测试应用程序,这不需要通过自己成为客户端来访问客户端。 5月16日10:56
  • ……一个人如何在没有首先接触客户或接触客户的情况下“冒充客户”或“自己成为客户”?你的评论毫无意义。
    ——施罗德
    5月16日11:12
2

每个用户添加的字符数不同!

[...]

这取决于两件事,然而,散列算法是保留的秘密,

这是所有人都需要知道的,才能知道这是一个坏主意。

您正在构建一个自定义方法,它依赖于方法的某些部分是机密的。你刚刚在stackoverflow上发布了这件事。

安全有时会与秘密一起工作,但秘密永远不在方法中,因为我们希望尽可能多的人来检查方法,以便比我们聪明的人能够发现我们没有看到的问题。

4
  • 谢谢你的回答,但请记住我是无安全性专家,正如许多其他人所指出的那样这是一个坏主意,这也是一个例子——我不会在我的web应用程序中实现它。但再次感谢你的回答,是的,人们永远不应该透露他们的默默无闻。 5月17日9:59
  • 一个人永远不应该首先是模糊的安全组件。
    ——日本1024
    5月17日16:27
  • @security_paroniid我指出,你只是发布了它,并不是为了羞辱你,而是为了向你展示你自己的陈述中的矛盾——你意识到一个安全想法应该被许多其他人检查,但你想对一个安全思想保密。你不能两者兼得。
    ——汤姆
    5月18日8:10
  • @汤姆,我从来没有生气过,我真的很喜欢你的答案,你百分之百正确! 5月18日9:02

你必须登录回答这个问题。

不是你想要的答案吗?浏览标记的其他问题.