我现在有一个(客户端/服务器通信)设置:
1)客户端要求用户输入用户名并传递
2)客户端使用端口80(通过Web)将其发送到服务器
3)服务器回答说这是否是正确的密码(correctpass / wrongpass),如果正确,它会向客户端发送加密密钥。
4)客户端向服务器发送一系列命令(所有命令都以服务器提供给客户端的加密密钥开始)。
5)服务器检查encryptionKey以识别客户端并响应命令
我的问题是:
这是保证安全的正确方法吗?我不确定来回发送一个加密密钥是否会有任何好处。让客户端生成加密密钥并让服务器验证它会有什么帮助吗?
我想要做的事情就像facebook在验证它的应用程序时所做的那样。例如,我可以想象facebook会阻止我通过wireshark或tcp分析器等程序窃取原始密码。
如果它很重要,我的程序是用c#编写的,并使用标准的http来发送/接收数据。
谢谢,
罗希特夏尔
答案 0 :(得分:5)
为了保持您正在做的大部分事情,您只需将步骤更改为
即可客户端要求用户输入用户名并传递
客户端建立与服务器的SSL连接。
客户端通过SSL连接发送用户名和密码。
服务器回答说这是否是正确的密码(correctpass / wrongpass)。
客户端向服务器发送一系列命令(所有命令都通过用于发送密码的相同SSL连接发送)。
服务器无需每封邮件都重新验证用户的身份,只要您使用一个连续的连接,SSL层就可以在幕后无形地为您完成所有工作。
另一方面,Facebook没有像你所描述的那样,他们使用OAuth。以下是OAuth如何工作的基本示例(来自yahoo的developer page)
因此,当您编写应用程序时,每个应用程序执行一次步骤1,每个用户执行一次步骤2-4以将应用程序与其帐户关联,然后您只需执行步骤5直到步骤4中收到的令牌过期(可能是几小时到几天,取决于网站)。令牌过期后,您只需重复步骤4(如果失败,则执行步骤2-4),用户可以再次使用该程序。
步骤3是他们输入密码信息的地方,但请注意他们在雅虎网站上输入密码,因此您的程序永远不会触及用户的用户名和密码(这就是OAuth的全部内容!)。
答案 1 :(得分:1)
一些一般指示:
正如其他人所指出的,如果可能,请使用SSL。
您应该从不以明文形式存储密码。相反,存储原始密码的哈希值并在比较之前重新传输任何收到的密码。如果您不能使用SSL,请让客户端在传输之前散列密码(使用MD5或类似代码)。
如果客户端是应用程序(不是浏览器中的页面)但您无法使用SSL,则客户端和服务器可以共享可用于加密传输的密钥。当然,秘密永远不会被发送,而是用作例如密钥。 AES加密。
在您的方案中,您可以使用例如由共享密钥,客户端IP地址和当前命令(或其子集)组成的字符串的散列,并将散列与命令一起发送,以便不断向服务器验证自己。
但请尽可能使用SSL。