如果您的虚拟主机允许,或者您需要处理敏感数据,请使用HTTPS句号。(法律afaik经常要求这样做)。
否则,如果您想通过HTTP执行某些操作。我会做这样的事情。
- 服务器将其公共密钥嵌入到登录页面中。
- 客户端填充登录表单,然后单击提交。
- AJAX请求从服务器获取当前时间戳。
- 客户端脚本将凭据,时间戳和盐(从模拟数据(例如鼠标移动,按键事件)中散列)连接起来,并使用公共密钥对其进行加密。
- 提交结果哈希。
- 服务器解密哈希
- 检查时间戳记是否足够新(仅允许短短的5-10秒窗口)。如果时间戳太旧,则拒绝登录。
- 存储哈希值20秒。在此时间间隔内拒绝用于登录的相同哈希。
- 验证用户。
因此,这种方式可以保护密码,并且无法重播相同的身份验证哈希。
关于会话令牌的安全性。那有点难。但是有可能使重用被盗的会话令牌更加困难。
- 服务器设置一个额外的会话cookie,其中包含一个随机字符串。
- 浏览器在下一个请求时发送回此cookie。
- 服务器会检查Cookie中的值,如果该值不同,则会破坏该会话,否则一切正常。
- 服务器用不同的文本再次设置cookie。
因此,如果会话令牌被盗,并且其他人发送了一个请求,则在原始用户的下一个请求上,该会话将被销毁。因此,如果用户积极浏览站点并经常单击链接,则小偷不会与被盗的令牌相去甚远。可以通过对敏感操作(例如帐户删除)进行其他身份验证来加强此方案。
编辑:请注意,如果攻击者使用不同的公共密钥设置自己的页面并向服务器代理请求,则这不能阻止MITM攻击。为了防止这种情况,必须将公钥固定在浏览器的本地存储区或应用程序内,以检测这些技巧。
关于实现:RSA可能是最广为人知的算法,但是对于长密钥来说它相当慢。我不知道PHP或Javascript实现的速度有多快。但是可能有更快的算法。