JWT 与客户端证书

信息安全 验证 证书 oauth 授权 jwt
2021-08-14 02:52:21

我们有一个由不同客户端应用程序连接的事务服务器。要求是为客户端应用程序提供一种安全的身份验证方式,以便与事务服务器进行通信。正在研究的两个解决方案是 JWT 和客户端证书。

在您看来,从安全性和效率的角度来看,这两种选择的优缺点是什么。我意识到这个问题有点笼统,特别是因为考虑到这些组件仍在开发中,我们希望在进入特定解决方案之前获得一些更通用的想法。

任何使用过这两种技术的人的建议都将不胜感激!

4个回答

对于一些上下文,我已经大量使用基于 JWT 令牌的身份验证,但对客户端证书几乎没有经验,所以我的回答会偏向于 JWT(信息和意见方面)。

JWT 代币优点:

  • 可以轻松生成(或重新生成),并且可以包含到期日期/时间,以减少因 JWT 令牌被盗而造成的损失
  • 可以在有效负载中包含“声明”以携带额外信息,可能是客户端设备的角色或您想要的任何键值对
  • 易于传输,因为一旦编码它们只是一个字符串
  • 绝大多数语言都有库来完成大部分繁重的工作。请参阅: 图书馆页面

JWT 代币缺点:

  • 您通常需要一个身份验证服务器或交易服务器上的一个模块来分配这些
  • 根据您的客户需要如何进行身份验证,事情可能会变得非常复杂或不可能。只要用户拥有登录凭据就可以了,因为这些凭据可用于在发送 JWT 令牌之前对客户端进行初始身份验证。否则,你需要一些手段来初步确认客户端的真实性

客户证书优点:

  • 需要安装一个证书(在配置时?取决于)一次
  • 不需要任何服务器端代码以与 JWT 相同的方式创建和分发证书

客户证书缺点:

  • 如果证书曾经被泄露,只要它是有效的(并且没有被发现被泄露,否则它可能被列入黑名单),它就可以用于重放式攻击
  • 需要客户端设备上的安全永久存储点。与可以安全地存储在内存中并最终在客户端关闭或应用程序关闭时销毁的 JWT 令牌不同,证书需要永久保存在安全位置。根据客户的具体情况,这可能非常困难或不可能

我的观点:JWT 令牌是一种安全、标准化的客户端身份验证方法,我会推荐它。

我在尝试帮助另一个论坛上的某人时偶然发现了这一点,这里的答案提供了有关客户端证书的信息,如果不是不正确的话,充其量是具有误导性的。

第一件事。

什么是客户证书?

客户端证书(用典型的说法)是一个X.509证书,就像让您的浏览器信任该网站的证书一样。使它成为“客户端”证书的原因是它由证书颁发机构签署,用于“客户端身份验证(1.3.6.1.5.5.7.3.2)”

换言之,CA 已确认该用途的证书。它在其他方面就像服务器证书一样。事实上,可以为“服务器身份验证(1.3.6.1.5.5.7.3.1)”和客户端身份验证签署一个证书。

发送证书是否会危及它?

不!单击浏览器中 URI 旁边的小锁并查看证书。您是否已破坏堆栈交换?一点也不。证书本质上是公开的。它们不包含任何秘密。

在证书身份验证场景(客户端或服务器)中,拥有私钥被视为身份证明。如果你的私钥泄露了,你就有问题了。无论这是客户端证书还是服务器证书,都是如此。

在使用证书(服务器或客户端)进行身份验证的过程中,不会交换来自私钥的秘密。它们还不受重放攻击的影响,这是您在使用 JWT 时需要考虑的问题。

如果我有不同的角色怎么办?

除了它的用途之外,客户端证书通常不用于授予授权。他们建立身份。该身份如何映射到权利是一个单独的问题。

为什么客户端证书很少用于客户端身份验证?

主要是因为大多数用户无法安全地创建、签名和管理私钥。我认为随着物理秘密管理组件变得越来越普遍,这种情况可能会发生变化。

什么时候客户证书是一个不错的选择?

当您拥有强大的 PKI 时。此外,我认为至少掌握公钥安全的基础知识是很重要的。例如,如果您正在运行需要在 Web 服务交互中充当客户端的 Web 服务器。如果您已经有一个服务器证书要管理,那么管理客户端证书(或对两者都使用一个证书)没有太多额外的开销。

在这种情况下,周围也没有用户可以输入密码或显示他们的脸或滑动手指。它可能在某个服务器场的机架上运行。您将如何向第三方验证此主机以生成令牌?如果您使用不断发送的密码或其他秘密来获取令牌,我质疑这种方法的智慧。

理想情况下,您将拥有某种HSM来存储秘密并且从不将其暴露在外部。这种方法变得更加普遍和负担得起。

如果不更多地了解您的环境,这是无法回答的。

  • 这都是在您自己的域内,还是这些外部连接到您的服务?
  • 这些服务是否需要彼此不同的权限集?
  • 这些服务是否用于委派下游使用的用户身份?
  • 这些服务如何相互通信?休息?二进制?
  • 您正在使用的技术堆栈是什么?

客户端证书作为一种身份验证方式很有用,但如果您的要求是对访问您自己的服务的服务具有不同的权限,则客户端证书本身无济于事。如上所述,您将需要管理您已颁发的证书 - 但此约束存在于需要签名的 JWT 中。如果您有多个外部证书,您将

如果消费者拥有不同的权限并通过 REST 访问您的服务,JWT 将非常有用。如果通信不是 REST,那么不要打扰 JWT。您还需要在 JWT 中管理签名证书。如果您要使用 JWT,请注意它们的弱点:

  • 针对尊重none的库的算法攻击
  • JWT 重放攻击
  • JWT 需要传输层上的 TLS
  • 一些 JWT 框架允许您通过将算法类型从 RS256 切换到 HS256 并使用公钥签名来攻击系统

正确实施 JWT 没有任何问题,只是人们可以搞砸 JWT 实施。我有偏见,因为我目前正试图在我自己的组织中解决导致安全漏洞的 JWT 模式,因为验证忽略了到期日期......

我觉得这里遗漏的一点是 JWT 和 SSL 客户端证书身份验证并不是真正直接竞争的技术。

JWT 令牌是会话 cookie、其他不记名令牌和其他类似的短期令牌(如 Kerberos 票证/令牌)的竞争技术,它不是主要的身份验证方式,而是在成功的主要身份验证后用于后续请求的令牌已经制成。要在到期后获得不刷新的 JWT 令牌集,客户端必须首先通过某种主要的身份验证方式进行身份验证,这些身份验证通常是某种形式的基于用户/密码的身份验证。

相反,SSL 客户端证书是一种主要的身份验证方式。就像上面示例中的用户/密码对一样。

这意味着甚至可以将 JWT 令牌生成给成功通过 SSL 客户端证书进行身份验证的客户端,然后将令牌用作对后续请求进行身份验证的手段。

事实上,出于性能原因(证书身份验证被认为是昂贵的),这种使用 SSL 证书进行身份验证的场景以及使用某种形式的短期令牌(通常使用会话 cookie,但“滚动你自己的安全事物”包含加密重要的不记名令牌的后续请求) - 请求数据并非闻所未闻,这基本上就是 JWT 的来源)是 SSL 证书身份验证传统上在 Web 应用程序中使用的方式。