当你打开浏览器访问某个网站时,如果网址旁边有一个小锁,表示访问的网站是安全的,否则就是不安全的。图片来自Pexels。当我们没有看到小锁图标时,就要提高警惕,不要随意输入重要的个人信息。所有银行和支付相关网站都是100%HTTPS。为什么我们需要HTTPS?为什么我们需要HTTPS?主要有以下三个原因:①隐私保护(Privacy):所有信息都是加密传输的,第三方无法窃听数据。如果使用HTTP明文传输数据,数据很有可能会被第三方劫持,那么输入的密码或者其他个人信息就会暴露给他人,后果可想而知。②数据完整性(Integrity):一旦第三方篡改了数据,接收方就会知道数据被篡改了,从而保证数据在传输过程中不被篡改——数据完整性。③身份验证:第三方不可能冒充参与通信,因为服务器配备了由证书颁发机构(CertificateAuthority,简称CA)颁发的安全证书,可以验证服务器的身份信息和防止第三方冒充身份。在少数情况下,通信需要客户端提供证书。例如,银行系统要求用户在登录时插入银行提供的USB,这就需要客户端提供证书来验证客户的身份信息。什么是HTTPS?什么是SSL/TLS?HTTP协议(HyperTextTransferProtocol,超文本传输??协议)是大家最熟悉的协议。它是一种传输超媒体文件的协议。它位于OSI网络协议模型中。应用层。但它是一种明文传输协议,非常不安全,容易被篡改和数据窃取。SSL(SecureSocketLayer)——Netscape设计的一种安全传输协议,主要用于Web。它位于TCP传输层协议和应用层协议之间。(它不属于OSI网络协议模型,被认为是应用层的一个子层。)众所周知,Netscape在1990年代终于在与微软的竞争中败下阵来,随后Netscape引入了SSL协议的管理被转移到IETF(互联网工程任务组,www.ietf.org)。于是IETF将SSL标准化,改名为TLS(TransportLayerSecurity)。1999年,TLS1.0(其实就是SSL3.1)诞生了。HTTPS(安全超文本传输??协议)基于SSL/TLS协议。信息通信通过SSL/TLS加密。最后一个S是Secure的缩写,代表安全。HTTPS=HTTP+SSL/TLS。SSL/TLS的发展史SSL/TLS的发展史如上图所示:事实上,现代浏览器基本不使用SSL,而是使用TLS。SSL3.0在2015年已经走到尽头,各大浏览器都不再支持了。但由于SSL这个名词存在的时间太久,所以在很多地方仍然被广泛使用,但要明确的是,它实际上指的是TLS。据调查,绝大多数浏览器(>99.5%)现在都使用TLS1.2或TLS1.3。不到1%的浏览器仍在使用TLS1.0或TLS1.1。TLS1.2仍然是主流协议(本文写于2020年初),相信未来TLS1.3会逐渐成为主流协议。许多浏览器将开始不支持TLS1.0和1.1:谷歌将在Chrome72中弃用TLS1.0和1.1,而Chrome81之后将完全不支持TLS1.0和1.1。Mozilla的Firefox、Microsoft的Edge和IE以及Apple的Safari将分别在2020年逐步取消对TLS1.0和1.1的支持。那么一些仍在使用TLS1.0和1.1的网站将不得不强制升级到TLS1.2或TLS1.3。要关闭浏览器对TLS1.0和1.1的支持,可以在Internet选项中修改:SSL/TLS的工作原理要了解SSL/TLS的工作原理,我们需要掌握加密算法。加密算法有两种:对称加密非对称加密对称加密:通信双方使用相同的密钥进行加密。特点是加密速度快,缺点是需要很好的保护密钥。如果密钥泄露,加密就会被他人破解。常见的对称加密包括AES和DES算法。非对称加密:需要生成两个密钥:公钥(PublicKey)和私钥(PrivateKey)。顾名思义,公钥是公开的,任何人都可以获得,而私钥是私密保存的。相信大多数程序员都已经熟悉这个算法了。我们在提交代码到Github时,可以使用SSH密钥:在本地生成私钥和公钥,私钥放在本地的.ssh目录下,公钥放在Github网站上。这样,每次提交代码时,都不需要输入用户名和密码。Github会根据网站上保存的公钥来识别我们的身份。公钥负责加密,私钥负责解密;或者,私钥负责加密,公钥负责解密。这种加密算法比较安全,但是计算量比对称加密大很多,加密和解密都很慢。一种常见的非对称算法是RSA。SSL/TLS利用了对称加密和非对称加密的特点。我们先看一下整个SSL/TLS握手过程,然后我们会一步步详细解释,每一步都做了什么。①TCP连接建立后,客户端发起TLS握手的第一步,向服务器发送ClientHello消息。ClientHello消息包含:客户端支持的SSL/TLS版本客户端支持的CipherSuitesSessionIdsessionid(如果有值,服务端会复用相应的握手信息,避免短时间内重复握手)RandomExtendedclient-random的读取:加密套件的名字是这样的:“TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA256”,这么长的名字可能看起来有点晕,不要怕,其实它的命名很规范,格式很固定.基本形式为“密钥交换算法-服务认证算法-对称加密算法-握手验证算法”。在握手过程中,证书签名使用RSA算法。如果证书验证正确,则使用E??CDHE算法进行密钥交换。握手后的通信采用AES256对称算法,分组方式为GCM。要验证证书签名的有效性,请使用SHA256作为哈希算法。相关算法的用处后面会详细说明。②服务端收到ClientHello后,选择服务端支持的版本和套件,发送ServerHello消息:服务端支持的最高SSL/TLS版本,服务端选择的加密套件,随机数server-random,sessionIdsessionid(用于下一次多路复用当前的握手信息,避免短时间内重复握手。)然后服务器发送服务器的安全证书(包括公钥)。如果要求客户端也提供证书,也会发出客户端证书请求(ClientCertificateRequest)。只有少数金融机构要求客户同时提供客户证明。之后,客户端发送ServerHelloDone消息表示Hello阶段完成。③客户端收到ServerHello后,会对收到的证书进行校验。我们来看看为什么网站的身份可以通过CA(CertificateAuthority,证书颁发机构)颁发的证书来确认。当我们安装操作系统或浏览器时,会列出一组受信任的CA(根证书CA,包括GlobalSign、GeoTrust、Verisign等)。GlobalSign等根CA在我们的受信任CA列表中,您的浏览器或操作系统包含GlobalSign公钥。我们先来看看谷歌的证书。当您访问Google时,Google会向您发送其证书。证书包含颁发机构的签名和服务器的公钥。浏览器首先使用哈希函数对明文信息的摘要进行哈希运算得到哈希值(使用证书中的签名哈希算法SHA256),然后使用根CA的公钥解密根CA的签名证书获取另一个哈希值(使用的算法是RSA非对称算法)。如果两个哈希值相等,则证书未被篡改。当然,还需要验证证书中的服务器名是否合法,证书是否过期。这样就避免了中间人攻击,因为如果中间人修改了证书的内容(比如用自己的公钥替换证书中的公钥),他会得到不同的哈希值,所以这两个哈希值不匹配。导致认证失败。要绕过这个机制,中间人也必须替换签名,使签名也匹配。为此,您需要破解根证书的密钥(这是不可能的,中间人不可避免地会失败)。浏览器中会出现如下画面,告诉你因为证书被篡改而遭受中间人攻击:你一定想到了,如果你开发的系统还在测试阶段,还没有正式申请证书,那么你可以为服务器自签一个证书,然后将证书导入到客户端的CA信任列表中。信任链机制如下图所示:可以看到证书路径为:GlobalSignRootCA-R2→GTSCA1O1→*.google.com因为我们的浏览器信任GlobalSignRootCA,根据信任链机制,你信任根CA签发的证书证书也必须信任它签发的子CA签发的证书,以及子CA签发的子CA签发的证书。并且我们已经通过了逐级验证。如果根证书到最低级别的证书没有被篡改,我们认为最低级别的服务器证书是合法的。所以在这个机制中,需要无条件信任根证书的颁发机构。如果通过身份验证,客户端会生成一个随机数pre-master,用于密钥交换过程。④密钥交换过程:客户端使用第三步从服务器的证书中得到服务器的公钥,并用这个公钥加密(算法是加密套件中的密钥交换算法,如ECDHE算法)生成密文并将其发送到服务器。⑤客户端使用server-random+client-random+pre-master一起计算对称密钥mastersecret。⑥服务器收到第四步的信息后,用服务器的私钥对密文进行解密,得到密钥pre-master。因为只有服务端有私钥,才能对客户端发送的加密信息进行解密,得到pre-master,保证只有服务端和客户端知道pre-master。服务端也可以同时使用server-random+client-random+pre-master来计算对称密钥mastersecret。现在客户端和服务端都有了keymastersecret,后面可以用来加解密。为什么我们不能直接使用pre-master作为后续加密的对称密钥呢?虽然只有服务器端有私钥,可以解密pre-master,但是用它作为mastersecret是不够安全的。这是因为要防止client.pre-master不是随机数的情况。再加上两个随机数client-random和server-random(这两个随机数是跟时间有关的),这样最后生成的mastersecret一定是随机数。⑦客户端用mastersecret加密握手完成消息发送给服务器。⑧服务器还发回消息,握手已完成,并使用主密钥加密。⑨当双方都收到对方发送的握手报文并成功解密后,就可以使用mastersecret愉快的开始数据加解密了。综上所述,整个握手过程主要是通过一系列步骤,通过非对称加密算法的交换获得主秘密。这一步通常需要数百毫秒,但经过这种暴力操作后,只有服务器和客户端知道主密钥。随后的通信使用高效的对称算法来加密和解密所有信息。虽然加密和解密也需要时间和流量,但是信息是完全不可能被他人篡改和破译的。这种损失是值得的。作者:StephanieTang编辑:陶佳龙来源:stephanietang.github.io/2020/04/19/how-https-works/
