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

我有一个nginx实例通过HTTPS提供Web应用程序。 Web应用程序同时提供浏览器和原生移动应用程序。 原生移动应用程序使用客户端证书作为附加authentication层,而Web浏览器仅使用用户名/密码。 浏览器和移动应用程序使用不同的path,但相同的TCP端点(IP /端口)。

问题是Web浏览器popup一个对话框,提示用户指定一个客户端证书。 取消这个对话框是完全正确的,因为它被configuration为在nginx中是可选的,证书的validation是在应用程序端完成的。 但是, 这对用户来说是非常混乱的 ,我需要弄清楚一个不显示对话框的方法。

我的要求:

  • 要有不同的端点是非常困难的(两者都需要端口443,分配一个新的IP将很困难)。 请不要build议更改端点。 我很清楚这个解决scheme,如果一切都是绝对不可能的,这就是B计划,但是这将涉及到很多很多很多的IT头痛。 避免改变终点很容易,需要花费几天的时间。
  • 除了改变端点之外,我完全控制客户端代码(即移动应用程序)以及服务器部署。 我可以根据需要更改协议,但需要在“普通”浏览器中支持HTTPS。
  • 如果每个path很难有不同的客户端证书设置(这个老的线程似乎表示),我可以采取基于用户代理的select。 这不是安全问题,因为应用程序validation证书是否用于“敏感”path。
  • 如果Nginx无法做到这一点,我会很乐意切换到另一个可以处理它的反向代理。 (Traefik,Apache,…?)

编辑:正如Krumelur指出的那样,TLS协议允许Web服务器启动会话重新协商,客户端可以根据需要请求客户端证书。 因此,下面的原始答案对这个问题是无效的。


证书authentication发生在TLS客户端 – 服务器握手期间,HTTP只在握手执行后才运行。

用户代理string是客户端通过TLS隧道发送的HTTP请求的一部分。 在TLS隧道build立之前,服务器不知道,客户端发送了第一个HTTP请求。

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

客户端Hello消息包含:

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

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

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

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

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

您唯一的select是使用@Alexey Tenbuild议的SNI