在浏览器中隐藏客户端证书对话框,同时仍允许客户端证书

在浏览器中隐藏客户端证书对话框,同时仍允许客户端证书

我有一个通过 HTTPS 为 Web 应用程序提供服务的 nginx 实例。该 Web 应用程序同时为浏览器和原生移动应用程序提供服务。原生移动应用程序使用客户端证书作为额外的身份验证层,而 Web 浏览器仅使用用户名/密码。浏览器和移动应用程序使用不同的路径,但使用相同的 TCP 端点(IP/端口)。

问题是 Web 浏览器会弹出一个对话框,提示用户指定客户端证书。取消此对话框完全没问题,因为它在 nginx 中配置为可选,并且证书验证在应用程序端完成。但是,这会让用户非常困惑,我需要想办法不显示对话框。

我的要求:

  • 拥有不同的端点会非常困难(两者都需要端口 443,而且分配新 IP 会很困难)。请不要建议更改端点。我很清楚这个解决方案,如果其他一切都绝对不可能,这是 B 计划,但这将带来很多很多 IT 麻烦。为了避免改变端点,花几天的时间进行开发是值得的。
  • 除了更改端点之外,我还可以完全控制客户端代码(即移动应用程序)以及服务器部署。我可以根据需要更改协议,但它需要在“普通”浏览器中支持 HTTPS。
  • 如果很难为每个路径设置不同的客户端证书(这旧线程似乎表明),我可以改用基于用户代理的选择。这不是安全问题,因为应用程序会验证是否对“敏感”路径使用了证书。
  • 如果 Nginx 无法做到这一点,我很乐意切换到另一个可以处理它的反向代理。(Traefik,Apache,......?)

答案1

编辑:正如 Krumelur 所指出的,TLS 协议允许 Web 服务器发起会话重新协商,客户端可以在需要时请求客户端证书。因此,下面的原始答案对于该问题无效。


证书认证发生在 TLS 客户端-服务器握手期间,并且 HTTP 仅在握手完成后运行。

用户代理字符串是客户端通过 TLS 隧道发送的 HTTP 请求的一部分。在建立 TLS 隧道并让客户端发送其第一个 HTTP 请求之前,服务器并不知道该字符串。

因此,唯一的选择是使用 TLS。现在,查看 RFC 5246 第 7.4 章,我们可以看到启动 TLS 握手的 Hello 消息的规范。

客户端 Hello 消息包含:

  • 当前时间
  • 28 个随机字节
  • 密码套件
  • 支持的压缩方法列表
  • 可能的 TLS 扩展

服务器随后会发回自己的 Hello 消息,并在 Hello 消息之后立即发送服务器证书。然后,它会发送服务器密钥交换消息,然后发送服务器证书请求(如果已配置)。

现在我们可以看到,客户端发送的唯一信息不包含任何有关客户端类型的信息。那里提供的唯一额外信息是 TLS 扩展部分,当前 TLS 扩展列表位于https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml

查看列表,即使在 TLS 扩展中也没有客户端类型信息。即使有这样的扩展,所有移动或所有桌面客户端都必须支持该扩展,系统才能正常工作。

因此,结论是,您无法实现在移动设备而不是桌面上使用客户端证书的目标,因为服务器无法知道何时需要客户端证书。

您唯一的选择是使用@Alexey Ten 建议的 SNI

相关内容