双哈希密码 - 客户端和客户端服务器

发布于 2024-09-05 00:20:21 字数 682 浏览 5 评论 0原文

嘿,首先,我要说的是,我不是在问诸如 md5(md5(...,已经有相关主题了。

我的问题是:

我们允许我们的客户在本地存储他们的密码。当然,我们不这样做不希望它们存储在计划文本中,因此我们在存储和/或发送之前在本地对它们进行 hmac 现在,这很好,但如果这就是我们所做的一切,那么服务器将拥有存储的 hmac,并且因为只有客户端。需要发送 hmac,而不是纯文本密码,攻击者可以使用服务器存储的哈希值来访问任何人的帐户(当然,在灾难性的情况下,有人会获得对数据库的此类访问权限)

。是通过 hmac 在客户端上对密码进行一次编码,将其发送到服务器,然后通过 hmac 对其进行第二次编码,并将其与存储的两次 hmac 密码进行匹配,这将确保:

  • 客户端可以存储 。本地密码,而不必将其存储为纯文本
  • 客户端可以发送密码,而不必(过多)担心其他网络方
  • 服务器可以存储密码,而不必担心有人从服务器窃取密码并使用它当然

,所有其他内容(强密码、双盐等)也适用,但与问题并不真正相关。

真正的问题是:这听起来像是一个可靠的安全设计吗?我们是否忽视了这样做的任何缺陷?是否有类似这样的安全模式?

附录:我们不想在客户端本地以纯文本形式存储密码的原因是,尽管令人悲伤,但许多人仍然在多个服务中使用相同的密码,因此获取“真实”密码将是一个更大的困难对于用户来说,安全漏洞比哈希被盗更重要。

Hey, first, let me say, I'm not asking about things like md5(md5(..., there are already topics about it.

My question is this:

We allow our clients to store their passwords locally. Naturally, we don't want them stored in plan text, so we hmac them locally, before storing and/or sending. Now, this is fine, but if this is all we did, then the server would have the stored hmac, and since the client only needs to send the hmac, not the plain text password, an attacker could use the stored hashes from the server to access anyone's account (in the catastrophic scenario where someone would get such an access to the database, of course).

So, our idea was to encode the password on the client once via hmac, send it to the server, and there encode it a second time via hmac and match it against the stored, two times hmac'ed password. This would ensure that:

  • The client can store the password locally without having to store it as plain text
  • The client can send the password without having to worry (too much) about other network parties
  • The server can store the password without having to worry about someone stealing it from the server and using it to log in.

Naturally, all the other things (strong passwords, double salt, etc) apply as well, but aren't really relevant to the question.

The actual question is: does this sound like a solid security design ? Did we overlook any flaws with doing things this way ? Is there maybe a security pattern for something like this ?

Addendum: the reason we don't want to locally store the password in plain text on the client is because as sad as it is, many people still use the same password for multiple services, so getting the 'real' password would be a bigger security breach for the user than getting his hash stolen.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

留蓝 2024-09-12 00:20:21

我正跑出门外,但双向飞碟发出了叮当声,你别乱动双向飞碟。

您正在做的是将密码替换为另一个常量值。您在这里一无所获,您拥有的唯一安全性是无法在客户端计算机上发现纯文本密码。

然后你要做的就是将密码的 HMAC(你确定你指的是 HMAC 吗?如果是的话,密钥来自哪里并存储在哪里?)作为密码本身 - 你将其从客户端发送到服务器,其中它用于验证。第二个 HMAC 或散列是没有意义的 - 您正在与发送的值进行比较 - 它是任何其他名称的密码。因此,作为攻击者,我不需要窃取密码,只需窃取存储在客户端计算机上的 HMAC。在这里什么也得不到。

I am running out the door, but the Skeet pinged and you don't mess with the Skeet.

What you're doing is replacing a password with another constant value. You gain nothing here, the only security you have is that the plain text password cannot be discovered on the client machine.

What you then appear to do is treating the HMAC (are you sure you mean HMAC? If so, where is the key coming from, and stored?) of the password as the password itself - you send it from the client to the server where it is used to authenticate. The second HMAC or hashing is meaningless - you're comparing against the value sent - it's a password by any other name. So, as an attacker, instead of stealing the password, I just need to steal the HMAC stored on the client machine. Nothing is gained at all here.

我恋#小黄人 2024-09-12 00:20:21

警告:我不是安全专家。我将 ping blowdart 看看他是否愿意加入。

客户端是否只是存储哈希值并有效传输某些内容仅仅基于哈希值,然后他们有效以纯文本形式存储它。第一个哈希提供的唯一好处是,如果他们在不同的系统上使用相同的密码,则即使哈希被泄露,其他系统也不会受到损害。

换句话说:如果有人可以获取存储在服务器上的哈希值,这就是他们登录系统所需的一切......就像纯文本存储一样。

Caveat: I'm not a security expert. I'll ping blowdart to see if he fancies joining in.

If the client is just storing the hash, and effectively transmitting something just based on the hash, then they're effectively storing it in plain text. The only benefit that the first hash is providing is that if they've used the same password on a different system, that other system won't be compromised if the hash is revealed.

To put it another way: if someone can get hold of the hash that's stored on the server, that's all they need to log into the system... just like plain text storage.

oО清风挽发oО 2024-09-12 00:20:21

正如其他人所说,将客户端和您的系统分开,这并不能真正给您带来任何好处 - 第一个哈希只是成为密码。

如果(很可能)客户端在其他系统上使用相同的密码,则该值就会出现。在这种情况下,如果客户端计算机受到威胁,那么至少其哈希密码的本地副本不允许攻击者访问其他系统。显然,客户端的攻击者现在将能够访问您的服务器 - 毕竟他们已经获得了密码。

有权访问服务器上的双重哈希值的攻击者不会向他们购买任何东西,因为他们无法反转该值以获得单一哈希值(即“密码”)。当然,如果攻击者能够读取您的安全数据库,那么我怀疑他们还有其他可用的攻击向量:)

另外,正如另一位海报所说,请确保您在两个哈希值上都使用了盐。如果不这样做,如果密码不强,反转哈希值实际上可能非常简单。

编辑 - 实际上,考虑一下,因为您使用哈希作为密码,所以您实际上不需要在服务器上使用盐。任何人都不可能创建一个有效的彩虹表:) 不过客户端仍然需要一个。

As others have said, taking the client and your system in isolation this doesn't really buy you anything - the first hash simply becomes the password.

The value comes if (as is likely) the client uses that same password on other systems. In this case, should the client machine be compromised then at least your local copy of their hashed password doesn't allow the attacker access to other systems. Obviously the attacker of the client will now be able to access your server - they have, after all, got the password.

An attacker having access to the double-hashed value on the server won't buy them anything, since they can't reverse that to get the single hash (i.e., the "password"). Of course, if the attacker is in a position to read your security database then I suspect they have other attack vectors available :)

Also, as another poster said, make sure you are using a salt on both hashes. Without doing so, reversing the hashes may actually be quite simple if the passwords are not strong.

EDIT - actually, thinking about it, since you are using a hash as the password you don't really need to use a salt on the server. No way anyone is going to be able to create a rainbow table that's effective :) Still need one on the client though.

許願樹丅啲祈禱 2024-09-12 00:20:21

不,这不安全。哈希值实际上就是密码。事实上,密码是从用户认为是密码的其他东西派生出来的,这一点并不重要。这是一个验证用户身份的秘密值,对吗?对我来说听起来像是一个密码。

我认为这取决于这样的说法:“当然,我们不希望它们存储在计划文本中,因此我们在存储和/或发送之前在本地对它们进行 hmac 处理。”如果系统被更改,使得散列密码现在具有与曾经具有的密码相同的权力,则应该对散列密码使用相同级别的谨慎。

No, this isn't safe. The hashed value is effectively the password. The fact the password was derived from something else that the user thinks of as the password doesn't matter. It's a secret value that authenticates a user, right? Sounds like a password to me.

I think it hinges on the statement, "Naturally, we don't want them stored in plan text, so we hmac them locally, before storing and/or sending." If the system is altered so that the hash password now has the same power the password once had, the same level of caution should be used with the hashed password.

我不是你的备胎 2024-09-12 00:20:21

吹镖击中了要害——你只是改变了偷窃的秘密,并没有保护任何东西。您尝试复制的是一种旧的身份验证协议,我一辈子都记不起它的名称。它的工作原理如下:

初始化时,服务器获取您的密码,迭代散列 n 次,用 Fn(pass) 表示。客户端有密码和数字n。

您进行身份验证,并向服务器发送 Fn-1(pass) - 即密码散列 n-1 次。服务器再次对其进行哈希处理,将其与 Fn(pass) 进行比较,如果它们匹配,您就可以获得访问权限。然后,服务器将 Fn(pass) 替换为 Fn-1(pass),然后递减 n。

下次您进行身份验证时,您发送 Fn-2(通过),然后重复该过程。

让我们检查一下安全性:

  • MITM:协议中没有内置的抵抗力,您必须将其分层到 SSL
  • 重放攻击中:它们不起作用,因为服务器已经减少了哈希迭代。
  • 窃听:下一次身份验证将使用 Fn-1(通过)完成。您有 Fn(通过)。根据哈希函数的定义,从 Fn(pass) 到 Fn-1(pass) 是不可行的
  • 拥有服务器:您不知道客户端的密码,您也不能以他们的身份进行身份验证,因为当您只有 Fn 时,您再次需要 Fn-1(pass)
  • 拥有客户端:因为您存储 F< sub>n-1(pass)(因此他们不必输入pass)-然后拥有客户端将让攻击者登录。如果您只存储 n 而不是密码,则会阻止这种情况,但您显然想保存密码。

这就是你想要实现的目标。然而,这个协议没有被使用是有原因的——它是一个巨大的同步问题。如果客户端和服务器由于完成了一半的步骤而失去同步,您将被锁定。您为避免这种情况而建立的任何弹性都可能会降低重放或窃听的安全性。

blowdart hit the nail on the head - you're just changing the secet to steal, not securing anything. What you're trying to replicate is an old authentication protocol that I can't for the life of me remember the name of. Here's how it works:

Upon initialization, the server gets your password, iteratively hashed n times, represented by Fn(pass). The client has the password, and the number n.

You go to authenticate, and send the server Fn-1(pass) - that is, the password hashed n-1 times. The server hashes it one more time, compares it to Fn(pass) and if they match you get access. The server then replaces Fn(pass) with Fn-1(pass) and you decrement n.

The next time you go to authenticate you send Fn-2(pass) and the process repeats.

Let's examine the security:

  • MITM: no resistence built into the protocol, you'd have to layer it inside SSL
  • Replay attacks: they don't work, because the server has decremented the hash iterations.
  • Eavesdropping: The next authentication will be done using Fn-1(pass). You have Fn(pass). Going from Fn(pass) to Fn-1(pass) is, by definition of the hash function, infeasible
  • Owning the server: You don't know the client's password, nor can you authenticate as them, because again you would need Fn-1(pass) when you only have Fn
  • Owning the client: Since you store Fn-1(pass) (so they don't have to enter pass) - then owning the client would let the attacker login. If you only store n and not the password this would be prevented, but you clearly want to save the password.

That's what you're trying to accomplish. However, there's a reason this protocol isn't in use - it's a giant bitch to syncronize. If the client and server get out of sync due to a half-completed step, you're locked out. Any resilience you built in to avoid that would likely reduce the security to replay or eavesdropping.

苄①跕圉湢 2024-09-12 00:20:21

我不太确定这比在本地以明文形式存储密码会给您带来什么。

本地加密的目的是防止黑客将密码发送到您的服务器。但是,如果您打算发送加密表格……那么您还没有购买任何东西。

相反,本地计算机应以双向加密格式存储密码。这意味着它可以被解密。您在传输之前执行的操作。数据库可以存储单向加密格式(甚至使用单独的加密机制)。在比较之前,您对收到的内容进行加密,然后进行检查。

I'm not exactly sure what this buys you over storing the password locally in plaintext.

The purpose of local encryption is to prevent a hacker from being able to send the password to your server. However, if you are going to send the encrypted form over... well, you haven't bought anything.

Instead, the local machine should store the password in a two-way encrypted format. Meaning that it can be decrypted. Which you do prior to transmittal. The db can store a one-way encrypted format (even using a separate encryption mechanism). Prior to comparison, you encrypt what you received then check.

扭转时空 2024-09-12 00:20:21

密码的初始哈希值旨在实现什么目的?它将防止密码的纯文本版本被发现。它不会阻止使用该哈希值来计算双重哈希值。

What is the initial hashing of the password intended to achieve? It will protect against discovery of the plain-text version of the password. It won't prevent the use of that hash value to calculate the doubly hashed value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文