我对不使用SSL保护PHP会话的主题感兴趣。
令我惊讶的是,如果中间人嗅探用户和服务器之间交换的数据包,即使会话经过身份验证,也很容易窃取会话。我知道有一些策略可以限制损害,例如,在登录/注销时更改会话ID,记录/检查用户系统参数(例如操作系统,浏览器)。
但是,如果在会话期间,已经经过身份验证且未注销(也没有时间超时),攻击者能够获取会话ID,那么他可以轻松劫持会话(据我所知)。
我想到了一个可能的解决方案,在加密的登录身份验证期间,服务器可以向客户端发送随机会话密码。会话密码仅在该登录会话期间有效。因此,在该会话期间交换的每条消息都必须使用会话密码进行签名(例如MD5(会话密码+消息内容))。
问题解决了吗?假设攻击者无法对初始登录交换进行加密分析,这种方法的弱点是什么?
您建议的"签名"解决方案需要客户端行为 - 因此您需要一个可以执行签名的客户端应用程序。
如果您正在编写 Flash/Java 小程序/Unity 或任何这些插件,那么您可以遵循您的计划,因为您可以更紧密地控制客户端并添加例程来执行签名。
但是我假设您在不使用插件的情况下将HTML页面发送到浏览器?如果是这样,你有两个选择,真的。拳头是SSL(你排除了),因为它内置在浏览器中。第二个是Javascript。为了获得最大的安全性,您需要以某种方式模仿SSL,包括加密(公钥)密钥/算法的客户端存储(这样它们就不会与消息一起传输)。您希望尽可能接近SSL的公钥/私钥+握手 - 这绝非易事。正如sarnold所建议的那样,您需要一个强大的加密密钥。查看 http://www.jcryption.org/示例 - 其他示例通过谷歌搜索出现。
如果这有点过分,你最可行的解决方案可能是使用 JS 协商一个更简单的加密算法:你发送一个"密钥",将"key"存储在浏览器上的 cookie 中,通过 AJAX 进行所有通信,然后你创建一个更简单的签名机制基于该密钥(可能还有客户端在初始握手期间与您共享的另一个变量)。任何不解码或不匹配密钥的内容,然后终止整个会话并重新开始。
萨诺德在他的回答中说,MD5和SHA-1是要避免的;有些人甚至认为SHA256是当今计算机的wesk,但考虑到你需要在JS中植入一个解决方案,为了速度,你可能会被绑在像md5这样"可怜的"(我的类比)上。因此,您对此的最佳防御是准确的日志记录和暴力/错误检测。任何到达乱码的消息(您可以在两端检查)都应被记录和监控。失败次数过多,IP 地址被禁止 - 并继续记录。
你想使用像HMAC这样的东西而不是更简单的MD5 - 并且你想使用SHA256或更大,因为MD5已知有弱点,SHA-1也开始感觉很弱。
但即使进行了这些更改,您的方案仍然容易受到重放攻击,攻击者可以一遍又一遍地重新发送请求,而您的服务器每次都会很乐意重新执行它。如果它只是发布最新海滩旅行的照片,这没什么大不了的,但如果它发送 1000 美元小马的购买请求,有人最终会得到比他们预期的更多的小马。
因此,您需要在协议中添加一个随机数。
还有其他问题 - 毕竟,经过三次SSL迭代后,TLS现在版本为1.2。只要坚持使用TLS并快乐。