如何保护密码不被客户端读取?

时间:2011-03-02 11:04:22

标签: php javascript xmpp ejabberd

我需要将服务器上的用户名和密码传递给我的网络聊天客户端javascript函数。当我通过javascript函数中的php代码发送用户名密码时,它对源中的用户来说是可读的,这是有害的。

请分享您的解决方案。

我从客户端的服务器A获取用户名密码,然后将这些凭据提交给javascript函数,然后连接到另一台服务器B.它就像facebook和gmail聊天工作,但他们做了什么来传递他们的用户凭据他们的javascript客户端连接到聊天服务器没有在网络上的任何地方提到,希望这解释得更好。

17 个答案:

答案 0 :(得分:18)

我向你保证这不是facebook和gtalk的做法。通常,他们处理支持第三方API开发(OAuth)的协议,该协议允许用户授予或拒绝应用程序使用其帐户。客户端应用程序在任何时候都不知道用户的凭据。这就是OAuth很受欢迎的原因。

您有几种选择,但我认为基于声明的身份验证是最佳方法。基本上,服务器A用于验证客户端并在系统中修饰其角色。这是通过HTTPS提供的加密cookie,以防止火灾羊型攻击。一旦在客户端上,服务器B可以询问该cookie以获得用户被授权在服务器B上执行的角色,如果加密则服务器B必须知道如何解密cookie。根据您的技术堆栈,有几个库可以支持这一点。同样重要的是要注意任何时候传输cookie(或任何安全令牌),它必须通过HTTPS发生,否则有效载荷可以通过不安全的无线网络截获。

编辑:根据我对该问题的评论,如果您使用的是XMPP,那么您可能会发现只需通过HTTPS对您的XMPP库进行身份验证就足够了。

答案 1 :(得分:13)

不要在Javascript中进行验证 - 在PHP代码中执行验证。

答案 2 :(得分:8)

很难从问题中判断出你的目标是什么,但看起来你想要限制客户端执行远程操作的方式。

您可以尝试让客户端向服务器请求授权密钥并让服务器在特定条件下接受密钥,而不是发送用户名和密码。

然后您可以通过以下方式限制密钥的使用:

  • 检查客户端IP地址和用户代理
  • 允许密钥仅使用一次(例如,将其用于数据库中)
  • 允许在生成密钥的时间限制内使用密钥

您应始终假设任何客户端操作都可能被欺骗。

如果我正确理解了这个问题,这些SO问题可能会尝试做类似的事情。

答案 3 :(得分:4)

只要您必须在浏览器上获取密码,用户就可以阅读它。 保护用户密码的唯一方法是永远不要将其发送到浏览器。

您也不应该使用密码的简单哈希,因为用户只需使用哈希而不是密码登录您的聊天服务器,而您没有解决任何问题。

实际上,你不应该在你的服务器上存储明文passsowrds,你应该存储一个哈希(最好是SHA-1,因为MD5已被成功破坏)。

你可以改为

  1. [聊天服务器]生成nonce,保存并将其发送到客户端
  2. [client]将随机数发送到第一台服务器
  3. [登录服务器]向客户端发送一个(SHA-1)散列a密码哈希加上nonce
  4. [client]将nonce和hash发送回聊天服务器
  5. [聊天服务器]根据您保存的列表检查随机数并删除它以防止重放攻击,然后再次计算哈希并检查它是否与您从客户端获得的内容匹配

答案 4 :(得分:3)

您无需验证密码。你只需要它的加密哈希。 实际上,即使在服务器端也不应该存储纯文本密码。

发送给客户:

sha1(sprintf("%s%s",salt,hash_from_db))

在客户验证:

sha1(sprintf("%s%s",salt, hash_func_as_on_srv(password))) == sha1_recieved_from_server

您可以生成您的salt表单唯一会话ID,远程IP或类似的东西。

答案 5 :(得分:1)

使用类似MD5的东西来存储密码,然后使用相同的“加密”传递passwd。

这样,只有用户才能知道自己的密码,不会以任何方式存储。

答案 6 :(得分:1)

如果您要从服务器A向服务器B发送(密码和用户名),那么如果您想使其安全,那么您必须为此提供某种安全机制(接口)。

我希望您先查看Two-way encryption: I need to store passwords that can be retrieved个问题。在这里,您可以存储key 加密某些value,即usernamepassword

例如: - 在服务器A中,我的用户名是user,密码是pass,我的密钥是asdfasdhfkshf,这是一个盐。在上面的解决方案中,您可以进行双向加密 - 解密。

每当我检索(使用javascript)我的usernamepassword时,我都会获得加密版本。我们可以说,使用密钥sfdasdfaskuyfgdkgh2145加密的“24sdf25asdf2asf42sad1fh”和“asdfasdhfkshf”。当然,没有人能够猜测,除非他们有密钥,并且密钥存储在服务器A中。

现在我们将这个加密的用户名和密码发送到服务器B,服务器B也存储相同的密钥和解密代码,当然,服务器B将能够将其解密回user和{{1} }。

因此,即使能够查看用户名和密码,用户也无法猜出。

但这仅适用于在服务器B中实现此接口或机制的情况。

答案 7 :(得分:1)

由于您不关心线路上的安全性,可以安全地假设您不关心使用其他工具(如fiddler / firebug或Wireshark)阻止用户获取数据吗?

如果是这样的话,已经建议你以这种方式使用AJAX,数据不需要成为可以使用“查看源”选项查看的源的一部分,或者在IE中按F12。

如果您希望防止用户名和密码在传递时被理解,则必须实施某种形式的加密。现在,根据你想让潜在的攻击者破解数据的难度,你可以做出一些选择。

您可以传递数据的MD5哈希值(假设两个服务器都可以访问原始数据)服务器B可以从原始数据生成MD5哈希值,并将其与客户端传递的哈希值进行比较。正如已经指出的那样,大多数Web应用程序都不会使用客户端证书或类似NTLM的用户对用户进行身份验证,这与重放攻击相关。

您可以选择不通过客户端传递用户名和密码,但使用仅指向数据库中用户名的一次性ID(GUID),并让服务器B在使用后删除该ID。这样,数据就会保密,避免重放攻击。 < - 不是加密技术,而是一个很好的解决方案。

您还可以研究许多其他加密技术,但我认为您希望保持简单。

答案 8 :(得分:0)

为什么你真的希望它存储在客户端?如果你需要在客户端提供某种标识符,那么实际上将它保存在服务器端,只是在客户端提供一个非人类可读的标识符,并且在其中进行更改会导致数据客户端在评估它时要访问它仅在用户有权访问时在服务器上。

答案 9 :(得分:0)

我认为最好的事情是通过PHP发送。

但你想特别使用JS,所以这里有一些我可以提供的东西;

对密码进行编码,md5();如果您不认为它是安全的,请尝试多层加密,如md5(sha1(sha1()))等。并将密码保存为数据库加密,以确保您的安全和用户的安全。因此,您可以使用不同的名称或“fun”等别名发送加密密码,以便向人们隐藏,以便知道密码。

此外,您可以使用PHP授权人们使用密码来代替发送密码,只需使用JS传递基于会话的随机“authorization_key”,该授权将在下次到期。

您也可以使用Ajax。我用上面讲的那些PHP和JS。

答案 10 :(得分:0)

  

(...)我从中获取用户名密码   服务器 A (...)

系统中有一个密码服务器听起来非常糟糕。相反,您可以使用 A 作为 B 的代理:客户端应该连接到 A ,这样可以提供进出 B的流量即可。当用户使用 A 成功进行身份验证后,可以使用存储的密码登录 B

另外,考虑整个设置也许是一个好主意。

答案 11 :(得分:0)

Facebook和其他社交网站实施OAuth(开放授权)技术,以安全的方式实现跨站点凭据共享。 您可以参考this了解更多详情。

答案 12 :(得分:0)

或者,您可以在访问其他服务器之前执行ajax调用,在此处请求user / pass。这样它就不会出现在你的JavaScript代码中。

答案 13 :(得分:0)

JavaScript中发生的任何事情都发生在浏览器上。这就是JavaScript被称为客户端语言的原因。永远不应该使用常规用户不应该知道的JavaScript进行验证或评估。

而PHP(服务器端)可以用于这些评估,因为所有这些评估都发生在Web服务器上,普通用户不会知道幕后发生了什么。

提示:使用AJAX和PHP可以提供应用程序所需的安全性和响应性。

答案 14 :(得分:0)

javascript:function(){getAlementByTagName('password')。value}在url中超过它

答案 15 :(得分:0)

第I部。
如果从服务器A获取用户名和密码以进行身份​​验证并登录到服务器B的用户正在使用服务器A的界面,那么您不必担心,因为当他手动登录时,他会做同样的事情。他在密码框中输入密码并点击提交。

您主要关心的是密码不应该通过网络以纯文本形式发送,因此不能被嗅探。使用SSL进行通信。

第二部分。
让我重新提一下你的问题举个例子,你想制作类似meebo.com(你的服务器A)的东西,一旦有人登录,他就可以使用Facebook聊天或Gmail聊天等等。要将用户登录到各自的聊天中,您将存储他们的密码并使用javascript将其发送到这些聊天服务器(您的服务器B)进行身份验证。

如果这是您想要的,那么您的方法是错误的,您的服务器A应该与服务器B通信并获取/推送所有数据。比如,服务器A应该有自己的聊天界面,如果用户向您的聊天服务器发送“Hi”,它应该在内部将该消息重定向(推送)到服务器B.服务器B的同一回复可以直接显示给服务器A界面中的用户。 这种方法的好处是你不必来回传输用户名和密码,使其不安全。

第三部分。
我还要补充一点,如果您要在服务器A的数据库中存储服务器B的用户名和密码,那么您必须让用户了解条款和条件。

答案 16 :(得分:0)

您可以在服务器端创建会话(使用http-api)并将其传输(会话ID等)到客户端会话

请参阅http://metajack.im/2008/10/03/getting-attached-to-strophe/