这里有两个单独的(ish)问题;身份验证和保密。如果您需要保密,请使用 HTTPS。然后您无需担心传输加密,只需以明文形式发送所有内容(因为 SSL 将为您执行完整的连接加密)。
至于密码存储;您永远不应该在任何地方存储明文密码。始终首先对密码进行哈希处理(至少,查找密码加盐以获得更强大的方法)并将哈希值存储在数据库中。当用户发送他们的密码时,对他们发送的内容进行哈希处理并将其与数据库中的值进行比较,如果它们匹配,则他们的密码是正确的。
如果您不想使用 SSL/HTTPS,那么您的想法是正确的,您需要避免以明文形式发送密码。您可以通过多种方式实现此目的,我认为最合适的是Challenge-Response,其中您通过生成随机字符串并将其回显到 javascript 变量中,从登录页面中的 php 发送随机“nonce”。
然后用javascript计算;
hash(hash(password) + nonce);
其中 hash 是一个安全的散列函数,例如 MD5 或 SHA。
这样,在服务器上,您可以验证密码,而无需用户以明文形式发送密码。通过将存储在数据库中的值与相同的 nonce 连接起来进行哈希处理,并将其与用户发送的值进行比较,如果值匹配,则密码正确。
所有这一切的重点是防止重放攻击,确保用户永远不会向服务器发送相同的登录字符串两次。攻击者可以窃听和记录任意数量的登录,在使用相同的用户帐户使用相同的 nonce 之前,它们都是无用的。避免这种情况只是使用非常大的随机数。
但是请注意,这种方法不能防止中继攻击或中间人攻击。这些类型的攻击需要相互验证,只能通过使用第三方来实现,例如证书颁发机构,这使我们回到 SSL/HTTPS。