在使用S3 样式身份验证的 RESTful API 中,API 客户端使用 HMAC-SHA1 使用其密钥对请求进行签名,因此密钥永远不会通过线路传输。然后,服务器通过使用客户端的密钥来验证客户端,以重复签名过程本身并将结果与客户端传输的签名进行比较。
这一切都很好,但这意味着服务器需要访问客户端共享密钥的明文。这违背了所有反对在数据库中明文存储用户密码的建议。据我所知,仅存储密码的加盐哈希不是一种选择-因为那样我就无法验证客户端的签名。
我应该强调我的 API 是 RESTful 的,因此应该是无状态的:我宁愿在其他 API 调用之前避免登录步骤。
一种可选的解决方案是使用某种对称密钥算法加密所有用户密码。但是,服务器必须将加密的密钥存储在易于访问的地方,例如源代码内部。这总比没有好,但不是最佳解决方案(正如@Rook 在他的回答中提到的,它违反了 CWE-257)。
解决方案的另一个方向可能是围绕非对称签名,但我不知道如何将其应用于 HMAC,也找不到任何关于该主题的文章。
我在这里遗漏了一些明显的东西吗?许多受人尊敬的提供商已经实施了这种身份验证方案——他们不可能都违反共同的安全原则,不是吗?如果没有,您是否可以分享任何最佳实践?