简单的握手仅能证明服务器知道证书的私钥。为了解决此问题,请让客户端信任多个证书。如果指定服务器的证书未出现在客户端可信证书集中,则该服务器不可信。
但是,服务器可能会使用密钥轮替将证书的公钥更换为新的公钥。当服务器配置发生更改后,就需要更新客户端应用。如果服务器属于第三方网络服务(例如网络浏览器或电子邮件应用),则更难确定何时更新客户端应用。
可信CA通常列在主机平台上。Android8.0(API级别26)包含100多个CA,这些CA在每个版本中都会更新,并且在不同设备之间保持一致。
客户端应用需要一种机制来验证服务器,因为CA为许多服务器提供证书。CA证书使用特定名称(如gmail.com)或使用通配符(如*.google.com)来标识服务器。
openssls_client-connectWEBSITE-URL:443|\opensslx509-noout-subject-issuerHTTPS示例假设您有一个由知名CA颁发证书的网络服务器,那么,您可以使用如下代码发起安全的请求:
请尽可能使用这些API。以下部分介绍了一些常见问题,需要采用不同的解决方案。
下面几部分将讨论如何解决这些问题,同时确保与服务器的连接安全无虞。
为了降低入侵风险,CA将根CA保持离线状态。但是,Android等操作系统通常仅直接信任根CA,这会在服务器证书(由中间CA签名)与证书验证程序(识别根CA)之间留下一个小的信任缺口。
为了消除此信任缺口,服务器在TLS握手期间会发送一系列证书,从服务器CA经由任何中间CA发送到可信根CA。
$openssls_client-connectmail.google.com:443---Certificatechain0s:/C=US/ST=California/L=MountainView/O=GoogleLLC/CN=mail.google.comi:/C=ZA/O=ThawteConsulting(Pty)Ltd./CN=ThawteSGCCA1s:/C=ZA/O=ThawteConsulting(Pty)Ltd./CN=ThawteSGCCAi:/C=US/O=VeriSign,Inc./OU=Class3PublicPrimaryCertificationAuthority---这表明服务器会为mail.google.com发送一个由ThawteSGCCA(中间CA)颁发的证书,为ThawteSGCCA发送另一个由VerisignCA(Android信任的主要CA)颁发的证书。
但是,服务器可能未配置为包含必要的中间CA。例如,下面的服务器会引发Android浏览器错误和Android应用异常:
有些网站会特意针对提供资源的辅助网络服务器执行此操作。为了节省带宽,它们会使用具有完整证书链的服务器提供主要的HTML页面,而用没有CA的服务器提供图片、CSS和JavaScript等资源。这些服务器偶尔会提供您正尝试从Android应用访问的某种网络服务,但遗憾的是,它们无法获得应用信任。
如需解决此问题,请将服务器配置为在服务器链中加入中间CA。大多数CA都可以提供有关如何为常用网络服务器执行此操作的说明。
为了降低此风险,Android提供了将某些证书甚至整个CA列入拒绝名单的功能。尽管此名单过去已内置到操作系统中,但从Android4.2开始,可以远程更新此名单,便于处理将来的泄露问题。
本文重点介绍了如何使用TLS来确保与服务器之间的通信安全。TLS也支持客户端证书的概念,客户端证书允许服务器验证客户端的身份。虽然这超出了本文的范围,但其中涉及的技术与指定自定义TrustManager类似。
在已知的TLS/SSL漏洞和错误配置方面,可以通过Nogotofail轻松确认您的应用是否安全。它是一款自动执行的工具,功能强大并且可扩展,用于测试通过它传送网络流量的任意设备的网络安全问题。
Nogotofail可用于三个主要用例:
Nogotofail适用于Android、iOS、Linux、Windows、ChromeOS和macOS操作系统。事实上,任何用于连接互联网的设备都可以使用Nogotofail。Android和Linux上提供了一个用于配置设置和获取通知的客户端,以及一个本身可作为路由器、VPN服务器或代理部署的攻击引擎。
当TLS服务器在TLS握手中发送证书请求消息时,某些浏览器(如GoogleChrome)允许用户选择证书。从Android10开始,KeyChain对象会在调用KeyChain.choosePrivateKeyAlias()时信任颁发机构和密钥规范参数,以向用户显示证书选择提示。需要注意的是,此提示不包含不符合服务器规范的选项。
如果没有可用的用户可选证书(当没有与服务器规范匹配的证书或设备没有安装任何证书时,便会出现这种情况),则完全不会出现证书选择提示。
此外,在Android10或更高版本上,无需具备设备屏幕锁定功能,就能将密钥或CA证书导入KeyChain对象中。
在Android10及更高版本中,系统默认会为所有TLS连接启用TLS1.3。以下是有关TLS1.3实现的一些重要的详细信息:
在Android10中,使用SHA-1哈希算法的证书在TLS连接中不受信任。自2016年以来,根CA未再颁发过此类证书,因为它们不再受Chrome或其他主流浏览器的信任。
如果某网站使用的是SHA-1证书,则任何尝试连接该网站的操作都将失败。