如果没有ssl,如何保护注册过程


How to secure the sign up process if there is no ssl

我正在为用户建立一个注册页面,让其作为成员注册,我想知道如果我没有ssl服务器,如何确保用户密码的安全。

我能想象的唯一方法是在将用户的密码发送回服务器存储之前对其进行md5加密,下次在登录页面时,密码输入将是带有动态秘密种子的md5,然后再发送回服务器以验证用户是否为成员。

这是个好主意吗?有什么好建议吗?我还有其他选择吗?

非常感谢你的好主意。

问题是,您需要客户端和服务器之间的某种共享秘密,而可能的窃听者不知道这些秘密才能对其进行加密。由于窃听者还可以事先监听客户端和服务器间的所有流量,因此您会遇到某种鸡和蛋的情况。

唯一的解决办法:使用公钥/私钥加密。客户端使用服务器的公钥加密密码,然后发送。唯一可能打开密码的人是私钥的所有者,可能是您的服务器。

看看http://www.jcryption.org,它可能会做你想做的事。

首先,即使您保护的资产不需要高度安全的方法,也值得尝试保护密码-因为太多人在不同的网站上使用相同的密码-然而,对于安全、面向公众的系统来说,SSL是无法替代的。

如果您使用来自服务器的质询对提交的密码进行散列,则可以做到这一点。您已经获得了一个合适的挑战,即PHP会话id(尽管您需要确保不易受到会话固定的影响,并且允许从Javascript读取会话cookie也有一些安全限制)。

当然,这取决于服务器上是否有一个未哈希的密码来创建比较值。这是一个明确的否定。

所以。。。。您将使用已知salt(S1)散列的密码存储在服务器上。当有人想登录时,你会向他们发送会话id(S2)和S1,他们会发回:

md5(S2 . md5(S1 .password));

md5有javascript实现。

Md5作为一种安全密码即将失效——然而,对于这里所说的puprose来说,它应该足够了。

我想你真的不需要解密它,因为人们通常只在数据库中存储密码哈希。(除非您想知道/获取他们的密码)。

一种常见的方法是拥有密码并只发送散列。

我建议您将"salt"从服务器端传递到表单,并将密码和salt散列在一起,使其更随机。

为了真正安全,您必须实现/找到一个用javascript实现的公钥加密算法。使用任何对称密钥加密仍然容易受到中间人攻击,因为您的密钥必须传输到客户端。

这个问题的真正解决方案是使用真正的SSL/HTTPS连接。

理由:

  • 如果登录后可用的内容值得保护,则必须保护整个会话,而不仅仅是用户密码
  • 如果内容不值得保护,为什么需要登录

请注意,您不需要使用付费SSL证书即可获得SSL的好处。您可以签署自己的(请参阅http://www.debian-administration.org/articles/284例如)。然而最近版本的Firefox已经让使用自签名证书成为一件麻烦事,除非用户准备好将您安装为CA。(按照某种奇怪的逻辑,Firefox显示的添加新CA的对话框远没有为使用自签名证书的单个服务器添加异常那么令人担忧。这真的很糟糕,因为接受新CA会接受该CA将来签名的所有证书!)

但是,如果您坚持不使用真正的SSL,则可以使用JavaScript实现加密:http://www.hanewin.net/encrypt/或http://www.jcryption.org/-请注意,这需要大量的工作,如果在每一个细节上都正确实现,最终结果可能会像SSL一样受到保护。最终结果将永远不会像SSL那样安全,因为您必须在没有加密的情况下将JS脚本传输到访问者的用户代理(浏览器),因此访问者最终可能会运行攻击者选择的JavaScript(攻击者可以执行中间人攻击,因为否则您也不需要对用户密码进行任何保护)。

存储在web浏览器中的证书颁发机构(CA)的公钥是唯一可以防止SSL/TSL不受中间人攻击的东西。因此,没有办法保护这些解决方案
所有这些解决方案都容易受到中间人攻击。

请注意,Mallory(恶意主动攻击者)可以在页面中替换他的公钥。

您应该使用SSL(其余的不那么安全)来进行身份验证,幸运的是,您可以像stackoverflow.com一样使用开源OpenID。例如,你可以通过阅读这篇文章来理解为什么Stackoverflow.com已经切换到OpenID(阅读良好)。

LightOpenID提供了一个非常用户友好的OpenID库。我在github上创建了一个小库"Openid for PHP,通过一种用户友好的方式选择Openid,感谢Openid选择器和LightOpenID"。我还在我的网络主机上放了一个演示,可以在http://westerveld.name/php-openid/