我有一个 REST API 后端,它具有 HTTPS(和阻止 HTTP)并使用 JWT 作为身份验证机制。客户端是 iOS/Android 应用程序。我想通过使用客户端随机数来为关键 API 添加一层保护,以防止(大部分)重新提交(由于网络/UI 不良而无意中调用相同的 API 两次)和(可能)重放攻击。目前的详细情况如下。
(所有 REST 调用都通过 HTTPS)
- 客户端使用用户名和密码进行 API 调用,以从服务器端交换 JWT。
- 客户端使用获得的 JWT(HTTP 标头)并随后对服务器进行 API 调用。
- 后端服务器检查 JWT 并执行请求。
当前的问题是,任何可以拦截 HTTP 包的人都可以重放 API 调用。此外,在网络不好的情况下,客户端可以按两次提交/确认按钮,然后重新提交请求。
我的建议如下:
- 客户端使用用户名和密码进行 API 调用,以从服务器端交换 JWT。
- 客户端使用获得的 JWT + 客户端生成的 nonce 并随后对后端服务器进行 API 调用。
- 后端服务器首先检查 JWT,然后检查 nonce。假设我们有一个类似 Redis 的带有 TTL 的 kv 存储。
- 如果 Redis 中存在 nonce,我们将拒绝该请求。如果不是,我们接受请求并在 Redis 中使用一些预定义的 TTL(比如 1 小时?)设置 nonce,以便拒绝重播。
我不得不承认我对安全知之甚少。我想知道这个提议是否合法?还是我错过了一些重要的事情?如果我的想法没问题,生成随机数的最佳算法是什么?在将它与 Redis 进行比较之前,服务器端是否需要以某种方式“解码”随机数以查看它是否符合协议?