ChatGPT解决这个技术问题 Extra ChatGPT

保护 API:SSL 和 HTTP 基本身份验证与签名

在为我们的 Web 应用程序设计 API 时,我们将使用他们的子域作为“用户名”并生成 API 密钥/共享密钥。首先,可以使用子域作为用户名吗?我看不到生成另一个密钥的好处。

不同的 API 似乎做以下两件事之一:

使用带有 SSL 的 HTTP 基本身份验证

在每个请求中,用户名都设置为子域,密码设置为 API 密钥。由于我们使用的是 SSL,所以这应该可以避免欺骗。

著名的 API:Google CheckoutFreshbooksGitHubZendesk

使用共享密钥创建请求的签名

通常通过对键/值对进行排序并使用带有共享密钥的 HMAC-SHA1 来生成签名来实现。然后签名随请求一起发送并在另一端进行验证。

著名的 API:Google CheckoutAmazon AWS

PS:没错,Google Checkout 两者都支持

编辑:刚刚读到 OAuth 2 正在放弃签名以支持通过 SSL 发送用户名/密码。

任何人对选择什么的任何意见:SSL 与签名?


M
Marcus

根据我的研究,基于 SSL 的 HTTP 基本身份验证非常安全。

毕竟,使用 SSL(现在严格来说是 TLS)意味着传输层是加密的,我们可以安全地假设通过它传递的任何信息都是安全的并且没有被篡改。

因此,在不生成签名的情况下传递用户名和密码就足够了。


e
emboss

伊戈尔的回答并不完全正确。尽管 TLS 确实确保了传输层的加密和安全,但它仍然不如使用具有相互身份验证的 TLS 安全,其中客户端使用数字签名形式的“强加密”进行身份验证。这仍然优于基于 TLS 的基本身份验证有两个主要原因:

密码就是密码,我假设地球上现在 70 亿人中有 3 人使用完全随机的 30 个字符的密码。我们其他人选择了熵少得多的东西。因此,攻击者更容易暴力破解使用密码而不是数字签名的服务。

有人可能会争辩说,对于客户端数字签名,还涉及到密码,通常用于访问私钥。但这仍然与我们使用基本身份验证的情况有很大不同:首先,私钥作为资源驻留在客户端计算机上,因此即使恢复它也只会影响一个人而不是每个人,其次,对于典型的密钥容器格式,例如 PKCS#12,还有用于访问密钥的基于密码的加密。这些算法专门设计用于减慢攻击者的速度,以降低他们每单位时间的蛮力尝试率,这也是数字签名的优势。

毫无疑问,TLS Basic Auth 的设置和使用更加方便,但对于高安全性环境,我总是更喜欢“强加密”而不是用户/密码解决方案,这是值得的。


好奇您对潜在中间立场的想法:基于 SSL 的 API 密钥?这使用不会被暴力破解的更长的“密码”。但是还是没有签约。所以我想它仍然 100% 依赖于 SSL 工作,但就像集成基本身份验证一样容易(如果不是更容易,1 个字段而不是 2 个)。
@BrianArmstrong:我同意。更好的熵,但仍然需要 SSL。不过,我真的很喜欢客户端身份验证方案的分散方面。另一方面,客户端机器可能比服务器更容易渗透。
M
Matt H

OpenSSL 的 Heartbleed 问题说明了仅依靠 SSL 来保护 API 的潜在缺陷。如果 SSL 传输受到损害,则根据 API 的使用和影响,可能需要采取额外的安全措施,如 Emboss 的回答中所述。


E
Evert

只要有某种形式的秘密,就可以使用子域作为用户名。

使用共享秘密的好处是,发出请求的“一方”不需要知道秘密,只需要知道签名即可执行请求。例如,如果您希望用户允许通过浏览器发出请求,这将非常有用。

使用 S3,您可以创建签名,将其发送到浏览器并从浏览器直接上传到 S3。

您还可以使用 HTTP Digest,这两者都有好处。您仍然可以在浏览器中轻松测试 API,因为浏览器支持 Digest 和 Basic,并且永远不会通过网络发送纯文本密码。


谢谢,但是,如果使用共享密钥,请求方当然必须知道密钥,以便计算签名!
签名的计算可以在服务器上完成,然后可以将签名发送到执行实际请求的不同客户端。看看 AWS 身份验证,我喜欢他们的身份验证方法,您可以按原样将其应用于您的 API。比自己开发更好。
好吧,我想我已经在这里回答了我自己的问题。 OAuth 2.0 使用不带签名的 SSL,我认为任何通过 SSL 的东西都是安全且好的。
O
Ogglas

我想指出 security.stackexchange.com 上提到的一些事情,因为您说“基于 SSL 的 HTTP 基本身份验证对于我的研究来说是完全安全的。”。您可能会争辩说,下面的第 3 点和第 4 点对 REST API 很少有效,但这实际上取决于它们的实现方式。

“HTTP Basic Auth 存在一些问题:

密码以 base64 编码(可以很容易地转换为明文)通过网络发送。

对于每个请求,都会重复发送密码。 (更大的攻击窗口)

密码由网络浏览器缓存,至少在窗口/进程的长度内。 (可以由对服务器的任何其他请求静默重用,例如 CSRF)。

如果用户请求,密码可以永久存储在浏览器中。 (同上一点,另外可能被共享机器上的其他用户盗用)。

其中,使用 SSL 只能解决第一个问题。即使这样,SSL 也只会保护到网络服务器——任何内部路由、服务器日志记录等,都会看到明文密码。

因此,与任何事情一样重要的是要查看整个画面。 HTTPS 是否保护传输中的密码? - 是的。

够了吗?通常,没有。 (我想说,永远不会——但这真的取决于你的网站是什么以及它需要有多安全。)”


C
Community

在一个旧线程上回答,因为没有人真正触及要点

与所有 PKI 一样,SSL/TLS 存在根本缺陷,因为它们依赖于已被证明越来越容易受到 MiM attacks 影响的信任链:

认证机构已经并且可能被黑客入侵。众多示例中的一个例子是 DigiNotar 案例,其中 CA 在确认违规之前被入侵数月,所有证书都被撤销。与此同时,伊朗政府为 google.com、facebook.com、twitter.com 等伪造了完美有效的 SSL 证书

公司代理过滤工具,如 Zscaler,可即时解密和重新加密所有流量,用于未指定的“安全目的”。在 SO 上查看此问题/答案

最常见的 SSL 实现 (openSSL) 的错误总是被发现(但随着时间的推移,事情应该会变得更好吗?)

因此大玩家不喜欢只依赖 SSL:

在这些情况下,HMAC 令牌不会为您提供机密性,但不会允许监视您的任何人使用您的凭据伪造请求,如果您只是通过基本身份验证传递它们,这将是微不足道的。

PKI 模型的替代方案是 Web of trust,它不依赖单一机构来验证证书的真实性,而是依赖于大多数已知且受信任的对等方或已知但不一定受信任的对等方提供的意见

这个模型仍然不是完美的,因为它受到臭名昭著的 51% attack 的影响,就像比特币区块链一样(这是分布式可信模型的一个例子)