【问题标题】:How do I keep my passwords secure?如何确保我的密码安全?
【发布时间】:2023-11-19 05:30:01
【问题描述】:

我现在有一个(客户端/服务器通信)设置,如下所示:

1) 客户端向用户询问用户名并通过

2) 客户端使用端口 80(通过网络)将其发送到服务器

3) 服务器回应说这是否是正确的密码(正确密码/错误密码),如果正确,它将向客户端发送一个加密密钥。

4) 客户端向服务器发送一系列命令(所有命令都以服务器提供给客户端的加密密钥开头)。

5) 服务器检查加密密钥以识别客户端并响应命令

我的问题是:

这是确保安全的正确方法吗?我不确定来回发送单个加密密钥是否会有任何好处。让客户端生成加密密钥并让服务器验证它会更有帮助吗?

我想做的事情就像 facebook 对应用程序进行身份验证所做的那样。例如,我可以想象 facebook 做了一些事情来阻止我通过诸如 wireshark 或 tcp 分析器之类的程序窃取原始密码。

如果这很重要,我的程序是用 c# 编写的,并使用标准 http 发送/接收数据。

谢谢,

罗希特

【问题讨论】:

  • 立竿见影的改进是切换到https。
  • 这是保证安全的正确方法吗? - 不。从端口 80 上的名称/密码开始。

标签: c# networking communication


【解决方案1】:

要保持您正在做的大部分事情都一样,您只需将步骤更改为

  1. 客户端向用户询问用户名并通过

  2. 客户端与服务器建立 SSL 连接。

  3. 客户端通过 SSL 连接发送用户名和密码。

  4. 服务器响应说这是否是正确的密码(正确密码/错误密码)。

  5. 客户端向服务器发送一系列命令(所有命令都通过用于发送密码的同一 SSL 连接发送)。

服务器不需要在每条消息中不断重新验证用户的身份,只要您使用一个连续连接,SSL 层就会在幕后为您完成所有这些工作。


另一方面,Facebook 与您所描述的完全不同,他们使用OAuth。这是 OAuth 工作原理的基本示例(来自 yahoo 的 developer page

因此,您在编写应用程序时对每个应用程序执行一次第 1 步,每个用户完成一次第 2-4 步以将应用程序与其帐户相关联,然后您只需执行第 5 步,直到第 4 步中收到的令牌过期(可能从几小时到几天不等,具体取决于站点)。令牌过期后,您只需重复第 4 步(如果失败,请执行第 2-4 步),用户可以再次使用该程序。

第 3 步是他们输入密码信息的地方,但请注意,他们是在 Yahoo 网站上输入密码,因此您的程序永远不会接触到用户的用户名和密码(这就是 OAuth 的重点!)。

【讨论】:

  • 共享密钥的用途是什么?
  • 共享密钥是用于对您的应用和 OAuth 提供者之间的所有消息进行数字签名的密钥。它证明您的应用程序确实是您的应用程序。它与消费者密钥不同,因为消费者密钥是您的应用程序在提供程序中的“ID”,它不是保密的。
  • 举一个真实世界的例子。对于您的 ATM 卡,您的银行帐号将是您的消费者密钥(印在您开出的每张支票上),但您输入 ATM 取款的密码是共享密钥。
  • 谢谢!这是一个很好的例子/解释
  • "只要你使用一个连续的连接" 比这更好。只要您在 SSL 会话有效期内使用相同对等点之间的一系列连接,SSL 就会共享会话。
【解决方案2】:

几个通用指针:

正如其他人指出的那样,尽可能使用 SSL。

您应该永远以明文形式存储密码。相反,存储原始密码的哈希并在比较之前重新哈希任何收到的密码。如果您不能使用 SSL,请让客户端在传输之前对密码进行哈希处理(使用 MD5 或类似方法)。

如果客户端是应用程序(不是浏览器中的页面)但您不能使用 SSL,那么客户端和服务器可以共享一个可用于加密传输的密钥。秘密当然不应该被发送,而是用作例如密钥。 AES 加密。

在您的场景中,您可以使用例如由共享密钥、客户端 IP 地址和当前命令(或其子集)组成的字符串的哈希值,并将哈希值与命令一起传输,以便不断向服务器验证您自己的身份。

但请尽可能使用 SSL。

【讨论】: