您需要在这里考虑几个因素。我希望您的 API 密钥有过期时间吗?即使这样做,如果对手控制了您的 HTTPS 请求,它也容易受到重放攻击。作为补救措施,您可以为您的请求引入时间戳或计数器。
反重放攻击
时间戳可以添加到消息中,并与消息内容的其余部分一起加密。服务可以在解密消息后检索时间戳,如果时间戳对于已经商定的阈值来说太旧,则请求失败。这减少了重放请求的机会窗口。这种方法的缺点是服务器和客户端都需要与时间同步。
时间戳的替代方法是计数器。使用计数器,您无需担心时钟之间的偏差。但是,客户端必须实现一个计数器,以确保请求中发送的计数至少比前一个请求中的计数大 1,并且服务器必须保留最后收到的计数器的记录。当然,必须对消息进行签名,以便恶意用户不会增加计数器并重播请求的其余部分。
基于散列的消息验证码来对抗 MITM 攻击
确保消息数据完整性的主要机制是基于哈希的消息验证码 (HMAC)。HMAC 只是通过加密哈希算法和共享密钥创建的一段数据。但是,如果需要对消息进行加密以确保机密性,您可以使用我们用于 HMAC 的相同私钥轻松添加该功能,或者您可以引入专门用于加密的新密钥。当用户发送请求时,您需要关注以下三个重要参数。
- 公钥,即与用户关联的密钥
- 柜台
- 时间戳
除了参数之外,请求还包括一个签名,以确保没有任何参数被篡改。如果目标是确保请求中没有任何内容被修改,则不仅可以基于三个参数创建签名,还可以基于请求的整个主体创建签名。为了确保没有人篡改参数,我们可以包含所有三个值的 HMAC-SHA256 以及请求 URI 和 HTTP 方法。
您可以在标题中引入以下 4 个属性。
X键
这是您的 API 密钥
X-签名
如果客户端应用程序在 X-Signature 中发送的值与 X-KEY、X-Counter、X-Stamp、请求 URI 和 HTTP 方法的值的 HMAC-SHA256 匹配,我们可以安全地得出结论,没有任何改变在途中。
X-邮票
将客户端发送的值与当前时间的 UNIX 时间进行比较。如果这两者之间的偏差在允许的容差范围内,则该请求不是重放。UNIX 时间是自协调世界时 (UTC) 1970 年 1 月 1 日午夜以来经过的秒数。
X-计数器
如果客户端发送的值大于服务器保存的记录中最后收到的计数器,则该请求不是重放。尽管我在本章的实现示例中同时使用了时间戳和计数器,但通常使用一个就足够了,具体取决于您的需要。如果时钟时间合理地同步,时间戳是最好的方法,因为在将计数器存储在 Web API 端或在客户端增加计数器方面没有开销。
结论
最好使用已经过实战考验的框架,例如 OAuth 来满足您的需求。但是,如果您认为它太复杂,则需要考虑此答案中正在解释的内容。