在 URI 中隐藏敏感数据

信息安全 休息 敏感数据暴露 乌里
2021-08-22 19:17:40

这是一个潜在的假设性问题,因为尚未确定我们是否需要这样做,但我认为这个问题会更频繁地出现。

背景

在实现RESTful 服务时,标准方法是 URI 包含识别相关资源所需的信息。虽然我不是餐厅主义者,但与我们希望利用的方法相比,这种方法有很多优势。

问题

我们遵守有关保护某些类型信息的法规要求。如果我们遵循基本的 REST 公式,其中一些受保护的元素将最终出现在资源路径中。

由于 URL 是加密的,TLS 将涵盖大部分问题。但是,有一些地方可以将它们存放在透明的地方。值得注意的是,默认情况下,它们通常被写入访问日志(这很有用),如果人们为此使用浏览器,它们可以清楚地存储在浏览历史记录中。

方法

假设这是一个问题并且我们想要使用这种方法,似乎有一个解决方案的主要竞争者,即加密部分 URI 或全部。散列似乎不是一种选择,因为数据是高度可预测的,并且计算整个值集很容易。加密整个 URI 将限制该方法的许多优点。对称加密需要广泛分发密钥,因此无法达到目的。似乎最好的选择是使用公钥加密敏感数据。

据我了解,您的加密输出至少需要与模数一样长因此,如果我们使用 2048 位密钥,则每个数据至少需要 256 字节。这将导致一些相当长的 URI,但我认为这在一段时间内应该没问题,而且这个限制可能并不真正适用于我们的解决方案。

这种方法似乎有效和/或我还缺少什么吗?使用与 TLS 相同的密钥对是否有效?加密部分可能需要一些其他信息以避免重放攻击或将加密值映射回给定密钥,对吗?

注意:我应该提到,对于我的具体问题,只有经过身份验证的方才能打电话。尽管可能会发生错误,但这并不是我们要在公共互联网上公开的内容。所有相关方都有法律义务保护数据。由于 RESTful 服务越来越受欢迎,我认为值得探索这种想法的更一般用法。

4个回答

似乎有一个解决方案的主要竞争者,即加密部分或全部 URI。散列似乎不是一种选择,因为数据是高度可预测的,并且计算整个值集很容易。加密整个 URI 将限制该方法的许多优点。对称加密需要广泛分发密钥,因此无法达到目的。似乎最好的选择是使用公钥加密敏感数据。

你的逻辑是合理的。

我知道一种产品完全符合您的建议;敏感数据在最终用户浏览器中通过 Javascript 代码进行加密,并发出 HTTPS GET 请求,其中一些“key=value”参数对具有公钥加密、base64 编码的字符串。

优点是这些请求可以通过具有多个 TLS 端点的网络传递,而无需对敏感数据进行解密,并且中间的任何 Web 服务器日志或代理都无法访问敏感数据。

这种方法似乎有效和/或我还缺少什么吗?

这是有效的,但这里有一些你不想错过的东西:

  1. 您需要一个具有足够智能的客户端来为您执行加密。这意味着 Javascript,或自定义应用程序,或其他东西。
  2. 不要推出自己的加密货币。使用可靠的、有信誉的库,并对您的应用进行代码审查。
  3. 密钥管理。您需要生成密钥、发布密钥、轮换密钥和停用密钥……而且您需要谨慎操作,因为正确操作意味着要在失去对数据的控制权和失去对数据的访问权之间取得平衡。

使用与 TLS 相同的密钥对是否有效?

我建议反对它。除了“不要使密码系统过载”的一般经验法则之外,在某些情况下,该密钥是不“受信任的”。我遇到的一个问题是 DDoS 缓解服务通常喜欢拥有您的 Web 证书和密钥的副本,如果它们在攻击期间引导您的流量。

加密部分可能需要一些其他信息以避免重放攻击

那要看; 如果您正在使用的 REST 事务是幂等的,那么它并不那么重要。如果它确实改变了某些东西,那么是的,重放保护更重要。

或将加密值映射回给定密钥,对吗?

是的,这不是绝对必要的——取决于你使用了多少个键以及它们的 OUP 和 RUP 尾部有多长——但不必猜测哪个键要容易得多:)

我被提醒了这一点,因为它是作为一个“热门问题”出现的。自从我问过这个问题后,我了解到OWASP 的建议是使用请求标头:

  • 在 POST/PUT 请求中,敏感数据应在请求正文或请求标头中传输
  • 在 GET 请求中,敏感数据应在 HTTP 标头中传输

虽然这使得 API 更难使用,但至少在一些常见框架中支持这种方法。

这种方法似乎有效和/或我还缺少什么吗?

但是,您的方法是有效的;由于以下原因,我不会拒绝使用预共享的对称密钥。

  • 非对称解密比对称要慢得多。如果服务必须从您的 URI 中解密多个值,则性能可能会受到影响。
  • 这种加密的攻击向量是有限的。在大多数情况下,TLS 应该保护这些数据。
  • 可以为不同的消费者提供不同的预共享密钥以增加安全性(解决您对广泛共享对称的担忧)。这也为密钥轮换提供了更大的灵活性。
  • 非对称加密会产生很大的加密文本。如果您的 URI + 查询字符串足够长,可能会导致 414(请求 URI 太长)

使用与 TLS 相同的密钥对是否有效?

从理论上讲,您不应该这样做,因为如果攻击者获得了您的密钥对,他们可以解密您的 TLS 连接和加密的标头。

...现在从现实/支持的角度来看,如果获得了您的 TLS 密钥对,那将是世界末日的场景。拥有第二个密钥对不会阻止“完全破坏”事件,因为您可能在标头/正文中有可以解密的敏感数据。

我认为您需要仔细权衡适合您特定业务需求的选项。

更标准的方法是将敏感信息移入体内。

真的,这取决于您的日志记录实践。您可以通过在日志中包含正文来使上述建议变得毫无价值,或者您可以通过不记录完整的 URI 来回避问题。您的服务器始终可以使用该信息(即使在您的加密方案中,也必须至少由堆栈的某些部分对其进行解密)。

在我看来,与其实现一个使 URL 膨胀、使调试变得更加困难并让用户想知道发生了什么的复杂方案,不如将日志中的默认值更改为适合您环境的默认值。