Skip to content

Latest commit

 

History

History
174 lines (120 loc) · 10.7 KB

2.1 https 协议全记录.md

File metadata and controls

174 lines (120 loc) · 10.7 KB

2.1 https 协议全记录

HTTPS全称Hyper Text Transfer Protocol over Secure Socket Layer,
直译过来就是通过SSL实现的超文本传输协议,简单来讲就是加密版的HTTP协议,也就是HTTP+SSL/TLS

HTTP是明文传输的,因此使用HTTP协议传输隐私信息非常不安全,很容易在传输过程中被窃取,或者通信内容被人篡改冒充,使用HTTPS可以避免这些问题。

实际上我们现在的HTTPS都是用的TLS协议,但是由于SSL出现的时间比较早,并且依旧被现在浏览器所支持,因此SSL依然是HTTPS的代名词。 上面一大段话是转载的,简单而言就是TLS是SSL的升级版,现在浏览器一般用的都是TLS

2.1.3 HTTPS的优点

  • 从底层分析HTTPS有以下3大优点:

    • 防窃听:信息被加密了,第三方拿不到密码,所以可以防窃听;
    • 防篡改:还是因为信息被加密了,如果执意篡改的话,客户端无法解密不说,而且数据完整性校验这一关也过不了;
    • 防冒充:防止攻击者冒充他人身份参与通信,比如HTTPS的双向认证;
  • 从实际出发来看,HTTPS主要有以下优点:

    • 防止私密信息泄露,防止信息被篡改;
    • 有助于SEO,百度、谷歌均明确表示会优先收录、展示HTTPS站点的内容;
    • 完全杜绝运营商HTTP劫持问题;
    • 有效解决运营商DNS劫持问题,降低网站被劫持的风险;
    • HTTPS的小绿锁表示可以提升用户对网站信任程度(当然不是说有小绿锁的都是安全的);
    • 可以有效防止山寨、镜像网站等;
    • 为未来升级HTTP/2做准备,HTTP/2必须基于HTTPS部署;

HTTPS的缺点

  • 服务器性能下降,开启HTTPS会增加内存、CPU、网络带宽的开销,特别是非对称加密这一块;
  • 访问速度下降,HTTP连接的建立需要3次握手,HTTPS还需要加上ssl的几次握手(具体是几次没去考究,有说是9次),当然下降主要是在第一次建立连接的时候,后面正常通信速度一般没啥变化;
  • 除了握手部分外,所有信息传输之后浏览器和服务器都要进行加密解密,又是一笔额外的开销;
  • 申请证书需要一笔花费,当然现在免费证书也很容易申请到,这个不算明显缺点;

一句话概括就是:性能和速度下降,但是具体下降多少呢,这个不太好讲,可以延伸阅读:HTTPS 要比 HTTP 多用多少服务器资源?

2.1.5. HTTPS原理

HTTPS主要分为单向认证和双向认证,99%的场景都只需要单向认证,

2.1.5.2 单向认证

具体过程如下: 浏览器访问一个https地址,同时向服务端发送支持的SSL协议版本、支持的加密算法、一个客户端生成的随机数(用于稍后生成”对话密钥”)等。 服务端给客户端返回要使用的SSL协议版本号、加密算法、一个服务器生成的随机数(也同样用于稍后生成”对话密钥”),另外还有一个最重要的,返回服务器端的证书,即公钥证书; 客户端收到服务器回应以后,首先验证证书是否合法,如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期、或者返回的公钥不能正确解开返回证书中的数字签名,就会向访问者显示一个警告,由其选择是否还要继续通信。如果证书没有问题,客户端就会从证书中取出服务器的公钥继续; 客户端向服务端发送自己所能支持的对称加密方案(注意是对称加密),供服务器端进行选择; 服务器端在客户端提供的加密方案中选择加密程度最高的加密方式; 服务器将选择好的加密方案通过明文方式返回给客户端; 客户端接收到服务端返回的加密方式后,使用该加密方式生成产生一个随机密钥(后续用作通信过程中对称加密的密钥),然后将该随机数用用证书中的公钥加密发给服务端; 服务器收到客户端返回的加密信息后,使用自己的私钥进行解密,获得最终的对称加密密钥。至此,客户端和服务端都得到一个随机密钥,并且这个密钥别人没法知道; 在接下来的会话中,服务器和客户端将会使用该密码进行对称加密解密,保证通信过程中信息的安全。

2.1.5.4 双向认证

双向认证和单向认证原理基本差不多,主要区别是除了客户端需要认证服务端以外,服务端对客户端也需要认证。什么场景下需要验证客户端呢?比如一些银行业务,银行会要求客户必须在电脑上插入它们签发的U盾之类的东西,或者安装什么控件,这里就类似客户端证书的概念,没有这个证书的人无法使用银行提供的业务。

2.2 CA

2.2.1 何为CA

CA(Certificate Authority),即证书认证机构,它的作用就是提供证书(即服务器证书,由域名、公司信息、序列号和签名信息组成)加强服务端和客户端之间信息交互的安全性,以及证书运维相关服务。任何个体/组织都可以扮演 CA 的角色,难的是你要能得到全世界各大操作系统、浏览器等的默认信任,能得到他们的默认信任,你也可以自己开一家CA公司了,这类证书通常叫做根证书。浏览器默认信任的 CA 大厂商有很多,比如 Symantec赛门铁克、Comodo、Godaddy、GolbalSign(百度微博等都是它签发的) 和 Digicert。

2.3 SSL证书

2.3.1 证书的种类

SSL 证书按大类一般可分为DV SSL 、OV SSL、EV SSL证书,又叫域名型、企业型、增强型证书

2.3.2. 证书的格式

一般来说,主流的 Web 服务软件,通常都基于 OpenSSL 和 Java 两种基础密码库。

Tomcat、Weblogic、JBoss等Web服务软件,一般使用JDK自带的Keytool工具,生成Java Keystore(JKS)格式的证书文件。 Apache、Nginx等Web服务软件,一般使用OpenSSL工具提供的密码库,生成 .key、.crt等格式的证书文件。 IBM 的 Web 服务产品,如 Websphere、IBM Http Server(IHS)等,一般使用 IBM 产品自带的 iKeyman 工具,生成 KDB 格式的证书文件。 微软的IIS使用Windows自带的证书库生成pfx格式的证书文件。

3.1第一步,生成证书

证书一般都是用openssl来生成,当然也可以用jdk自带的keytool来生成,但是最终还是要用openssl来转换格式,所以一般还是推荐用openssl来生成。

3.1.2.1 安装openssl

首先当然还是安装openssl,这里我们只介绍Windows平台,Linux系统的请参考这里,点击这里下载Win64位的安装包

安装很简单,安装完毕之后为了使用方便,建议配置一下环境变量:

3.1.2.2. 生成CA根证书

我们先生成一个自己的CA根证书ca.crt,然后再用这个根证书生成服务端证书server.crt,有人会问, 为啥不直接生成服务端证书呢?因为这样做的话将来我们只要导入一个CA根证书,其它所有用它生成的证书都默认是可信任的,方便嘛!

好了,说了这么多废话,下面开始了:

# 生成CA私钥
openssl genrsa -out ca.key 1024
# 生成CA根证书,-day指定证书有效期
openssl req -new -x509 -key ca.key -out ca.crt -days 365

就这么简单,第二步需要输入几个东西,虽然说乱填也可以,但建议按照提示来填,其中Common Name需要特别注意, 如果是生成CA证书的话,可以输入诸如My CA之类的,如果是生成服务端证书的话,必须输入网站的域名,可以输入泛域名,如*.haoji.me

3.1.2.3. 生成服务端证书

和CA证书的生成不同的时,我们需要先生成一个csr证书请求文件文件(CSR,Cerificate Signing Request), 有了这个文件之后再利用CA根证书生成最终的证书:

# 生成服务端私钥
openssl genrsa -out server.key 1024
# 生成证书请求文件
openssl req -new -key server.key -out server.csr
# 生成最终证书文件,-day指定证书有效期
openssl x509 -req -days 365 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt

以上证书在Chrome55下测试没问题,但是Chrome61下测试提示Subject Alternative Name missing错误:

The certificate for this site does not contain a Subject Alternative Name extension containing a domain name or IP address.

提示必须指定DNS Name或者IP地址,而指定这个必须要用v3的证书。 生成v3证书只需要比上面多加2个参数-extfile openssl.cnf -extensions v3_req,但是多了一个额外的配置文件, 这个文件里面可以填很多东西(完整配置文件参考这里),我们这里仅仅需要指定subjectAltName即可。

先准备一个名为openssl.cnf的文件,内容如下:

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost.com
DNS.2 = www.localhost.com
DNS.3 = www.test123.com
#IP.1 = 127.0.0.1

解释一下,这里的alt_names指的是最终可以访问的域名或者IP,所以,其实一个证书是可以多个网站同时使用的。被访问域名只要满足DNS和IP中的一个,其证书就是合法的。

然后再来重新生成证书,为了对大家产生误导,我们再来一遍完整的过程:

# 生成服务端私钥
openssl genrsa -out server.key 1024
# 生成证书请求文件
openssl req -new -key server.key -out server.csr
# 生成最终证书文件,-day指定证书有效期
openssl x509 -req -days 365 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -extfile openssl.cnf -extensions v3_req -in server.csr -out server.crt

3.1.2.4. 生成客户端证书

如果需要实现HTTPS双向认证,还要按照上述服务端一模一样的操作再生成一个client.crt和client.key,这里我们就不重述了,90%的场景都是不需要双向认证的。

3.1.2.5. Windows导入证书

上述步骤执行完之后生成了如下文件:

我们只需要双击ca.crt导入这个自制根证书即可,以后只要是利用这个证书生成证书浏览器都会认为是可信任的,这让我想起了12306干的勾当,如果你能把你这个根证书推广到全世界的电脑和手机,那么你也可以成立一家CA公司专门卖证书了,哈哈。

导入的时候注意证书存储位置

参考