推荐的方法。我建议您使用 SSL并使用其密码对客户端进行身份验证。然后你就不需要任何花哨的 MAC、哈希、PBKDF2 等。
细节。 您询问了如何对用户进行身份验证。这是一个简单的方法。在站点范围内使用 SSL。当用户登录时(通过 Web 客户端输入密码),然后设置一个会话 cookie,该 cookie 在会话的其余部分记住用户。(确保始终使用 SSL,并在所有 cookie 上设置安全标志。)如果需要,您可以在用户验证后设置持久安全 cookie,这样他们就无需在此浏览器上再次输入密码。
如果您想从专用的移动客户端访问 Web 服务,同样的方法也可以正常工作。Web 服务器可以发送一个安全的持久性 cookie,应用程序可以将其永久存储在其应用程序本地存储中,并且可以使用该 cookie 来验证客户端。
备择方案。如果由于某种原因无法实现上述操作,则有一些备用替代方案,但我认为它们不太可取,并且更有可能出现安全问题。这是一种合理的后备方法:
在您的移动客户端应用程序首次启动时,它会提示用户输入密码,通过 SSL 连接到服务器,并通过 SSL 发送密码。服务器以随机的 128 位身份验证密钥(由服务器使用加密强度 PRNG 选择)进行响应。
客户端应用程序将此身份验证密钥永久存储在应用程序本地存储中。服务器永久记住此身份验证密钥与用户帐户之间的关联。
来自客户端应用程序的所有未来请求都使用此身份验证密钥进行身份验证,如下所示:您将一个参数附加到 URL 的末尾,该参数包含 URL 其余部分的 HMAC(在分配给此客户端的身份验证密钥下),任何 POST数据,以及服务器将考虑的任何其他状态。
只要所有请求都是幂等的(例如,对于非幂等操作,您确保在 URL 参数或 POST 数据中的某处包含唯一标识符,并且服务器会进行重放检测),这应该可以正常工作以保护从客户端到服务器的请求的真实性和完整性。
但是,它有一些安全限制。它不保护机密性。它也不保护其他请求标头、响应数据和各种其他内容。因此,它不如仅使用 SSL 安全。例如,使用这种方法构建的站点可能无法抵御中间人攻击,因为有大量其他内容不受 HMAC 保护,因此无法安全使用一个开放的 Wifi 网络。出于这个原因,我建议您只是全面使用 SSL 并简化您的生活,而不是尝试发明自己的加密请求身份验证格式。
防止密码猜测的安全性。您会注意到,我提出的任何方法都没有涉及根据用户密码生成加密密钥。用户通常选择密码。您应该期望在移动平台上尤其如此,输入密码很痛苦。出于这个原因,从密码派生的加密密钥通常会提供较弱的安全性,并且通常可以通过字典搜索来破解。例如,如果加密密钥是从密码中派生的,则捕获任何一个请求的窃听者将能够发起暴力密码搜索攻击以恢复密码,从而恢复加密密钥。
虽然 PBKDF2 试图尽可能地缓解这种情况,但根本的漏洞仍然存在。出于这个原因,我认为最好尽可能避免使用从密码派生的加密密钥。面对弱用户密码,我的上述解决方案更加稳健,因为它们不涉及通过任何连接以明文形式发送密码或任何作为密码函数派生的内容。
第三方设计。您提到您聘请了第三方来进行设计,他们建议使用 MD5(秘密 + 数据 + 更多数据)之类的东西。这是个坏主意。不要这样做。它有多个加密缺陷。首先,MD5(secret + data) 是一个糟糕的消息认证码;它容易受到消息扩展攻击。其次,通过连接来组合不同类型的数据是一个坏主意,也是十大最常见的加密错误之一;因此,亚马逊和 Flickr 都存在引人注目的安全漏洞。相反,我建议您使用正确的消息身份验证代码(如 HMAC),并使用正确的方法来连接要验证的数据字段,例如,通过包括长度字段。