我们可以谈谈客户端证书吗?

2021-01-23 15:00:42

我正在努力改进API用户通过SourceHut API进行身份验证的方式。今天,我正在为此目的阅读RFC 6749(OAuth2),这让我开始思考原始的OAuth规范。我隐约地回忆起,API客户端实际上在每个请求上签名了,是的,确实如此。这也让我开始思考:还有什么要求? TLS!

OAuth非常复杂。 RFC的长度为76页,单独的承载令牌RFC(6750)的长度为18页,并且从未有人阅读过它们。还要添加JSON WebToken(RFC 7519,30页)。该过程很复杂,每个人都可以自己执行-这是在安全性至关重要的组件中犯错误的可靠方法。并非所有数据都经过身份验证,任何步骤都涉及加密,而且任何一方很容易以意外状态结束。服务器必须处理自身撤消和生成安全令牌的问题。您是否遇到过对OAuth持肯定态度的人?

现在坐喝杯咖啡。我想谈谈客户端证书。他们为什么不起飞?让我们草拟一个假设的基于TLS的协议,以替代OAuth。图片如下...

作为API客户端开发人员,您需要生成证书颁发机构和中级证书,然后将CA证书作为注册为用户代理的一部分上载到服务提供商。

如果您希望用户授权您访问其帐户,则会为其生成证书,然后将其重定向到带有CSRin拖曳的服务提供商的授权页面。您的证书包括(其中包括)您想要被授予访问权限的授权范围列表。它已经使用您的客户端CA密钥或其中间体之一进行了签名。

客户检查所需的访问权限并表示同意。它们连同签名的证书一起被重定向回您的API客户端应用程序。

TLS基本上是互联网上经过最严格,最可靠的安全测试的机制,并且每个平台都可以使用成熟的实现方式。每个人都自己实现OAuth,而且通常实施情况很差。

客户端证书是无状态的。它们包含证明客户有权访问的所有必要信息。

如果您使用nginx,haproxy等处理SSL终止,则可以在应用程序后端甚至看到未经授权的请求之前就拒绝它们。

如果服务提供商是恶意的或丢失了其私钥,则可以通过一次吊销来取消信任客户的CA。

API客户端和服务提供者都始终确定该过程是由API客户端故意启动的。没有像OAuth一样使用怪异的状态令牌来进行该过程!

许多免费功能:您喜欢的任何元数据,内置的到期时间,APIclients都可以自行决定将其自组织为中间体,等等。

具有安全意识的最终用户可以在其帐户中切换一个标志,该标志将作为同意过程的一部分,要求他们在将签名的证书返回给API客户端之前自行对API客户端的证书进行签名。然后,必须由API客户端,服务提供商和用户对授权用于该用户帐户的任何API请求进行签名。

再举一个例子:假设您的组织有多个服务,每个服务代表用户与Acme Co的API子集进行交互。您的组织会生成一个单一的根CA,并使用它注册Acme Co的API。然后,您将中间CA颁发给您的每项服务,只允许为其所需范围子集颁发CSR。如果任何一项服务遭到破坏,就无法使用它来获得比现有服务更多的访问权限,并且您可以仅撤销其中一种中间产品,而不会影响其余部分。

由于该系统更加集中,因此即使在某些著名的缺点(例如CRL和OCSP)也得以缓解。您控制将要验证证书的所有端点,只要它们进入就可以直接将撤销分配给它们。

优势显而易见。让我们将其包装成一个可爱的Google-ableable,为其编写一些漂亮的工具和帮助程序库,然后发布它!

或者可能不是。我a不安,觉得自己在这里错过了一些东西。几十年来,每个人都将这样一个显而易见的解决方案留在桌面上似乎并不对。也许仅仅是整个证书签名舞在每个人的口中都留下了不好的味道-我们中的许多人对使用糟糕的OpenSSL CLI生成aCSR不太满意。但是,如果有动力,我们没有理由不能做得更好,更精简。

客户端证书还有更多用例,这些用例似乎很引人注目,例如用户密码的替代品。 Web浏览器对客户端证书的支持完全糟透了,但这是一个可解决的问题。

出于记录,我无意将这种方法用于SourceHutAPI。这个想法只是发生在我身上,我想听听你的想法。为什么我们不使用客户端证书?