生成可撤销的一次性 URL

信息安全 加密 休息 网址
2021-09-07 03:23:41

我需要生成一个一次性使用的 URL,它应该具有以下功能:

  1. 由于 URL 查询参数可能包含敏感信息,因此应该对其进行加密(在加密之上https)。
  2. 一旦使用,该 URL 将无法再次使用。
  3. URL 会在一定时间后自动过期。
  4. 管理员应该可以撤销有效的 URL。如果用户稍后尝试使用此 URL,他应该会看到相应的错误消息。

为此,我可以想到两种高级方法:

  1. 生成一个随机数作为 URL 的查询参数。将随机数和相应的参数(即真正的查询参数、过期、撤销状态、使用状态)存储在数据库中。当用户使用 URL 时,请检查所有必需的前置条件并将其标记为已使用,然后再提供真正的查询参数。
  2. 嵌入真实的查询参数和过期时间戳作为 URL 的查询参数。使用 AES256 等算法加密 URL。但是,我仍然需要将 URL 存储在数据库中,以便提供撤销功能。

基于上述,我倾向于选项 1,因为所有逻辑都在一个地方,而且看起来更安全。是否有任何行业最佳实践来处理此类问题?

如果重要的话,这将是托管在 IIS 上的基于 REST 的 Web 服务。

3个回答

看起来你很清楚自己在做什么。

一次性链接模式对于电子邮件验证之类的事情非常常见。通常,您会将过期日期存储在数据库中和/或在 URL 中使用签名字符串,该字符串包括要签名的字符串中的过期日期。这些只是避免信任用户输入的预防措施。

如果您想真正彻底,您可以将实际的随机 ID 或令牌 URL 发送给他们,然后在数据库中存储一个哈希值,以避免有人在数据泄露时使用该令牌。

您对提议的 AES 加密参数的上下文非常模糊。我通常会在消息正文中包含 URL 路由不需要的敏感信息,而不是 URL。这样,它就不会出现在 Web 服务器或代理日志中。AES 加密的数据也可能很快让您超过 URL 长度限制,具体取决于明文内容的大小。

编辑:为了完整起见,Azure 存储 SAS 令牌是不需要数据库记录且可撤销的加密方法的一个很好的例子。撤销是通过更改服务的 API 密钥来完成的……这将撤销由同一密钥颁发的所有令牌。

鉴于我没有很多关于正在使用的系统的信息,我建议使用更简单的数据库查找,而不是任何需要加密复杂措施的解决方案。

此外,为了使加密方法作为一次性链接工作,服务已知的并包含在 URL 中的某些参数必须在使用链接时进行更改。此参数不必是数据库查找,但确实需要进行持久更改。例如,如果链接是一次性上传 URL,则上传目录中存在文件可能会使 URL 无效。

最后,数据库存储的值更简单,因为只有一个来源可以检查有效性。使用无数据库解决方案,您需要检查秘密(即加密密钥),以及在首次使用后使链接无效的任何因素。

为 URL 参数使用对称加密会给您一个优势:它消除了进行数据库查找的需要。缺点是您引入了需要保护和维护的秘密(加密密钥)。由于无论如何您都需要进行数据库查找以检查吊销状态,因此您没有任何好处。所以我会选择方法#1。

确保使用足够长的 ID:s,并使用 CSPRNG 生成它们。正如 nbering所说,确保对它们进行散列(不加盐)以在发生违规时保护您。

像谷歌这样的软件巨头使用签名 URL 的方法

前提很简单,您发送一个带有与查询的未加密端匹配的加密字符串的请求。然后你需要做的就是在服务器上解密它。

例如

example.com?file=file.ext&time={unixtimecode}&{encryptedstringthatmatchesfileandtimestamp}

使用加密密钥是为了确保服务器/有权访问密钥的人发出的请求用户可以遵循一定的时间,并且请求没有被篡改。撤销字符串就像删除临时加密密钥一样简单,这意味着服务器无法解密请求,即使它被缓存了。