以安全的方式向服务器发送密码
Sending passwords to server in a secure way
我目前正在为我的一个网站开发一个更好的登录例程,我想解决安全地将登录数据传输到服务器的问题。有几篇关于这个主题的文章和帖子,但他们经常对如何完成有完全不同的看法。
从 SSL 开始,几乎每个人都在同一页上:您应该使用 SSL,我也这样做。然后还有人说:"That is enough, with SSL you can send username & PW as plaintext"。我不同意。其他人说它仍然应该被散列。我读了几篇文章,感觉人们关心登录例程的不同方面,并提出了仅处理其安全方面的机制。
那么我想知道的是,到目前为止我所阐述的例程是否足够,太多还是太少。我将尝试解释为什么我选择实现某个功能以及我尝试涵盖的安全方面:
- SSL:
服务器和客户端之间的通信应该始终是 https:// - 不过我读了几篇警告 SSL 是 "no silver bullet" 的文章,但这是一个好的开始。
- 哈希 PW 客户端(SHA3、ARGON2i、BCRYPT):
很多评论确实拒绝了私服。使用哈希,将其与数据库中经过哈希处理的 PW 进行比较,只需将 PW 从用户输入更改为哈希——攻击者仍然可以通过简单地获取哈希来访问。我同意。但是(这就是我的意思是人们阅读了有关安全性的不同方面)那些声称它比发送明文更好的人,因为在那种情况下只有你的系统,而不是具有相同 PW 的其他系统会受到损害(除非,当然他们还使用哈希 PW)。所以我会在通过 SSL 发送密码之前对密码进行哈希处理。
- 正在加密 HASH:
让我们假设 SSL 无法隐藏我们发送到服务器的数据,并且攻击者会读取经过哈希处理的 PW。我能想到的针对这种情况调整安全性的唯一方法是使用服务器事先发送的密钥加密(例如 AES CBC)客户端 HASHed PW,并且有效期很短.密钥必须随机生成。这样,服务器就可以解密数据,然后将HASH与它的数据库进行比较。
总结一下:
-> 客户端希望通过 SSL 登录 -> 服务器发回密钥 -> PW 的客户端散列 -> 使用密钥和随机 IV 对 HASH 进行客户端加密 -> 服务器使用密钥解密数据(存储在 $_SESSION 中,带有过期时间戳)并将 HASH 与他的 DB 中的 HASH 进行比较(如果过期时间戳仍然有效)。
这是个好方法吗?或者这太多了? (安全性会不会太高?)或者您有其他解决方案吗?
SSL 很好,我不知道你为什么不同意。客户端散列仍然使 PW 在客户端可见 以及散列 ,因此在那里没有任何收获。
问题归结为,"what are you protecting?"我的猜测是您没有保护任何比银行需要更多安全性的东西,而且可能远低于银行。
您花了很多时间在这里重新发明轮子,而不是依赖久经考验的真实方法。坚持已被证明的东西。
-> Clients wants to Login via SSL -> Server sends back a key -> Clientside hashing of the PW -> clientside encryption of teh HASH with the key and a random IV -> Server decrypts the data with the key (stored in $_SESSION, with an expiration timestamp) and compares the HASH with the HASH in his DB (if the expiration timestamp is still valid).
为什么要加密散列?这意味着散列不够安全。好吧,好吧,让我们开始吧。因此,让我们假设攻击者能够读取散列,这就是您想要使用附加层保护它的原因。如果攻击者能够读取散列,他们也能够读取服务器发送给客户端的密钥,以及包含加密算法的 Javascript(假设你在谈论HTML 场景)。现在攻击者拥有复制和反向加密的一切,事实上他们也可能首先改变从服务器发送到客户端的 Javascript。
为了防止那种发生,你需要一些包装器来保护客户端和服务器之间的所有通信,比如,哦,嗯,比如说...... SSL.
由于 SSL 已经保护通信免受第 3 方干扰……您认为您添加的额外歌曲和舞蹈究竟是什么?我告诉你:没什么。
Or is this too much? (Can there be too much security?)
您谈论它就像安全是一种液体,必须填满容器而不会溢出。这不是它的工作方式,你问错了问题,这意味着你试图解决错误的问题。这与您堆积的措施数量无关,而是它们是否以及如何解决特定问题。
如果问题是保护传输中的数据,那么解决方案是 TLS (SSL) - 这就是它专门设计的目的,在最好的情况下,你能想到的任何东西都是它的替代品很差。您无法超越 TLS 数十年的研究和实践。
虽然 Jay Blanchard 已经回答了...我想指出你犯的错误,因为否则它看起来像是一个人的话与另一个人的话(你可能会听,但其他读者可能不会):
- SSL:
The communication between server and client should always be https:// - nevertheless I read several articles warning that SSL is "no silver bullet", but it is a good start.
既是灵丹妙药又不是灵丹妙药,就看你怎么看了。
当我们谈论保护传输中的数据时,它就是解决方案 - 某种程度上的灵丹妙药。
但这并不意味着不会及时发现缺陷,或者您只需打开它并说 "I have TLS, I am secure!" - 不,它仍然需要随着时间的推移进行适当的配置、维护和调整。从这个意义上说,它不是灵丹妙药。
它也没有解决许多其他安全问题,所以当有人问 "How do I make my application secure?" 时,您当然会说这不是灵丹妙药 - 许多威胁需要单独解决,而且没有一站式解决方案全部.
- Hash PW clientside (SHA3, ARGON2i, BCRYPT):
Many comments did reject hasing PW. Using a hash, comparing it to a HASHed PW in the database would simply change the PW from the userinput to the HASH - an attacker would still have access by simply getting hands on the HASH. I agree. BUT (this is what I meant that people read about different aspects of security) the ones claiming that it is better than sending plaintext because in that case ONLY your system, but not other systems with the same PW would be compromised (unless, of course they use also hashed PWs). So I would implement HASHing of the password before sending it via SSL.
恰恰相反 - 当您在客户端对密码进行哈希处理时,这只会使 您的 站点上的帐户在数据泄露后更容易受到损害。
在数据库中查找哈希值 - 密码就在那里,这就是您找到的部分。但是该哈希仍然是某个用户提供的字符串的结果......没有什么可以阻止攻击者应用相同的技术来破坏哈希以破坏其他服务器上的帐户。
所以,这并没有以任何方式解决问题,但您可能会认为在最坏的情况下它不会做任何坏事......好吧,它间接地做了 - 你必须做一个相当大的努力,以实现有很多潜在错误的东西。
在最好的情况下,你只是在浪费时间,但一个小错误可能是一个重大漏洞。
此外,SHA-3 是一种加密 原始 - 它有很多应用,但主要是作为构建块。您不能只将它的一轮放在密码上并对生成的哈希感到满意。
作为比较,bcrypt 内部使用了 Blowfish(作为与 SHA-3 同类的原语),但你不能将 Blowfish 等同于 bcrypt。
- encrypting the HASH:
Let's assume SSL could not hide the data we send to the server and an attacker would read the HASHed PW. The only way that I could think of to adjust the security to this scenario, would be to encrypt (e.g. AES CBC) the client-side HASHed PW with a key that has been send beforehand by the server, and that has a short expiration period. The key would have to be generated randomly. Like that, the server can decrypt the data, and then compare the HASH with the one it its database.
加密密码哈希值是有正当理由的,但不是为了这个目的,当然也不是在客户端。
你需要一个安全的密钥交换协议才能工作。猜猜你是怎么做到的? TLS.
通过网络传输加密密钥或密码实际上没有什么不同。因此,即使这是保护密码的某种解决方案,您将如何在密钥本身上再次应用它?没有意义。
我目前正在为我的一个网站开发一个更好的登录例程,我想解决安全地将登录数据传输到服务器的问题。有几篇关于这个主题的文章和帖子,但他们经常对如何完成有完全不同的看法。
从 SSL 开始,几乎每个人都在同一页上:您应该使用 SSL,我也这样做。然后还有人说:"That is enough, with SSL you can send username & PW as plaintext"。我不同意。其他人说它仍然应该被散列。我读了几篇文章,感觉人们关心登录例程的不同方面,并提出了仅处理其安全方面的机制。
那么我想知道的是,到目前为止我所阐述的例程是否足够,太多还是太少。我将尝试解释为什么我选择实现某个功能以及我尝试涵盖的安全方面:
- SSL:
服务器和客户端之间的通信应该始终是 https:// - 不过我读了几篇警告 SSL 是 "no silver bullet" 的文章,但这是一个好的开始。
- 哈希 PW 客户端(SHA3、ARGON2i、BCRYPT):
很多评论确实拒绝了私服。使用哈希,将其与数据库中经过哈希处理的 PW 进行比较,只需将 PW 从用户输入更改为哈希——攻击者仍然可以通过简单地获取哈希来访问。我同意。但是(这就是我的意思是人们阅读了有关安全性的不同方面)那些声称它比发送明文更好的人,因为在那种情况下只有你的系统,而不是具有相同 PW 的其他系统会受到损害(除非,当然他们还使用哈希 PW)。所以我会在通过 SSL 发送密码之前对密码进行哈希处理。
- 正在加密 HASH:
让我们假设 SSL 无法隐藏我们发送到服务器的数据,并且攻击者会读取经过哈希处理的 PW。我能想到的针对这种情况调整安全性的唯一方法是使用服务器事先发送的密钥加密(例如 AES CBC)客户端 HASHed PW,并且有效期很短.密钥必须随机生成。这样,服务器就可以解密数据,然后将HASH与它的数据库进行比较。
总结一下:
-> 客户端希望通过 SSL 登录 -> 服务器发回密钥 -> PW 的客户端散列 -> 使用密钥和随机 IV 对 HASH 进行客户端加密 -> 服务器使用密钥解密数据(存储在 $_SESSION 中,带有过期时间戳)并将 HASH 与他的 DB 中的 HASH 进行比较(如果过期时间戳仍然有效)。
这是个好方法吗?或者这太多了? (安全性会不会太高?)或者您有其他解决方案吗?
SSL 很好,我不知道你为什么不同意。客户端散列仍然使 PW 在客户端可见 以及散列 ,因此在那里没有任何收获。
问题归结为,"what are you protecting?"我的猜测是您没有保护任何比银行需要更多安全性的东西,而且可能远低于银行。
您花了很多时间在这里重新发明轮子,而不是依赖久经考验的真实方法。坚持已被证明的东西。
-> Clients wants to Login via SSL -> Server sends back a key -> Clientside hashing of the PW -> clientside encryption of teh HASH with the key and a random IV -> Server decrypts the data with the key (stored in $_SESSION, with an expiration timestamp) and compares the HASH with the HASH in his DB (if the expiration timestamp is still valid).
为什么要加密散列?这意味着散列不够安全。好吧,好吧,让我们开始吧。因此,让我们假设攻击者能够读取散列,这就是您想要使用附加层保护它的原因。如果攻击者能够读取散列,他们也能够读取服务器发送给客户端的密钥,以及包含加密算法的 Javascript(假设你在谈论HTML 场景)。现在攻击者拥有复制和反向加密的一切,事实上他们也可能首先改变从服务器发送到客户端的 Javascript。
为了防止那种发生,你需要一些包装器来保护客户端和服务器之间的所有通信,比如,哦,嗯,比如说...... SSL.
由于 SSL 已经保护通信免受第 3 方干扰……您认为您添加的额外歌曲和舞蹈究竟是什么?我告诉你:没什么。
Or is this too much? (Can there be too much security?)
您谈论它就像安全是一种液体,必须填满容器而不会溢出。这不是它的工作方式,你问错了问题,这意味着你试图解决错误的问题。这与您堆积的措施数量无关,而是它们是否以及如何解决特定问题。
如果问题是保护传输中的数据,那么解决方案是 TLS (SSL) - 这就是它专门设计的目的,在最好的情况下,你能想到的任何东西都是它的替代品很差。您无法超越 TLS 数十年的研究和实践。
虽然 Jay Blanchard 已经回答了...我想指出你犯的错误,因为否则它看起来像是一个人的话与另一个人的话(你可能会听,但其他读者可能不会):
- SSL:
The communication between server and client should always be https:// - nevertheless I read several articles warning that SSL is "no silver bullet", but it is a good start.
既是灵丹妙药又不是灵丹妙药,就看你怎么看了。
当我们谈论保护传输中的数据时,它就是解决方案 - 某种程度上的灵丹妙药。
但这并不意味着不会及时发现缺陷,或者您只需打开它并说 "I have TLS, I am secure!" - 不,它仍然需要随着时间的推移进行适当的配置、维护和调整。从这个意义上说,它不是灵丹妙药。
它也没有解决许多其他安全问题,所以当有人问 "How do I make my application secure?" 时,您当然会说这不是灵丹妙药 - 许多威胁需要单独解决,而且没有一站式解决方案全部.
- Hash PW clientside (SHA3, ARGON2i, BCRYPT):
Many comments did reject hasing PW. Using a hash, comparing it to a HASHed PW in the database would simply change the PW from the userinput to the HASH - an attacker would still have access by simply getting hands on the HASH. I agree. BUT (this is what I meant that people read about different aspects of security) the ones claiming that it is better than sending plaintext because in that case ONLY your system, but not other systems with the same PW would be compromised (unless, of course they use also hashed PWs). So I would implement HASHing of the password before sending it via SSL.
恰恰相反 - 当您在客户端对密码进行哈希处理时,这只会使 您的 站点上的帐户在数据泄露后更容易受到损害。
在数据库中查找哈希值 - 密码就在那里,这就是您找到的部分。但是该哈希仍然是某个用户提供的字符串的结果......没有什么可以阻止攻击者应用相同的技术来破坏哈希以破坏其他服务器上的帐户。
所以,这并没有以任何方式解决问题,但您可能会认为在最坏的情况下它不会做任何坏事......好吧,它间接地做了 - 你必须做一个相当大的努力,以实现有很多潜在错误的东西。
在最好的情况下,你只是在浪费时间,但一个小错误可能是一个重大漏洞。
此外,SHA-3 是一种加密 原始 - 它有很多应用,但主要是作为构建块。您不能只将它的一轮放在密码上并对生成的哈希感到满意。
作为比较,bcrypt 内部使用了 Blowfish(作为与 SHA-3 同类的原语),但你不能将 Blowfish 等同于 bcrypt。
- encrypting the HASH:
Let's assume SSL could not hide the data we send to the server and an attacker would read the HASHed PW. The only way that I could think of to adjust the security to this scenario, would be to encrypt (e.g. AES CBC) the client-side HASHed PW with a key that has been send beforehand by the server, and that has a short expiration period. The key would have to be generated randomly. Like that, the server can decrypt the data, and then compare the HASH with the one it its database.
加密密码哈希值是有正当理由的,但不是为了这个目的,当然也不是在客户端。
你需要一个安全的密钥交换协议才能工作。猜猜你是怎么做到的? TLS.
通过网络传输加密密钥或密码实际上没有什么不同。因此,即使这是保护密码的某种解决方案,您将如何在密钥本身上再次应用它?没有意义。