我们都知道HTTP是非常不安全的,不安全的根源在于HTTP是明文传输。你在谷歌搜索了一个关键词,HTTP数据包从你的计算机传送到服务器的过程中,中间经过的任意一个设备都可以轻松解析你的数据包,获取你的关键词,你的隐私毫无保障。 你的信息被人获取只是明文传输的其中一个问题。总体来说,明文传输有三个问题:
不仅是HTTP,所有明文传输的协议,都有这三个问题。那解决方案自然也是围绕着这三点进行,我们需要有一个协议,能够保证:
这个协议就是 SSL/TLS历史
1999年,互联网标准化组织ISOC接替网景公司,发布了SSL的升级版 工作原理SSL/TLS协议的核心是 那么SSL/TLS协议的基本原理就是,客户端获取服务器的公钥,加密信息以后传送给服务器,然后服务器使用私钥解密。这个方案有两个问题。
针对第一个问题,我们需要一个办法来保证服务器传输的公钥确实是服务器的,而不是第三方的。这个时候,我们需要使用 数字证书 。数字证书由权威机构(CA, Certificate Authority)颁发,里面包含有服务器的公钥,证书文件使用CA私钥进行加密。当客户端与服务器建立加密通信的时候,服务器不再返回公钥,而是返回他的数字证书。客户端拿到证书,使用对应的CA的公钥解密,然后获取到服务器的公钥。这里有一个问题,客户端怎么拿到CA的公钥呢?如果还是去CA服务器获取的话,那么我们又会回到问题的原点即怎样保证CA公钥不被人篡改。因此,大部分浏览器中,权威CA的公钥都是内置的,不需要去获取。这就保证了CA公钥的正确性。第三方没有办法伪造证书,因为第三方没有CA的私钥(当然,CA被入侵的例子的也是有的,技术永远解决不了人的问题)。 针对第二个问题,SSL/TLS协议在通信过程中,并不是使用RSA加密,而是使用对称加密,对称加密的密钥(对话密钥)由双方协商生成。 因此,SSL/TLS协议的基本流程如下:
具体流程根据上面的论述,SSL/TLS协议的核心便是怎样安全的生成一个 对话密钥 来加密之后的通信。这个过程称之为 握手 。
握手一共有四次请求,注意,这些请求都是明文的(也没法加密)。 客户端请求(ClientHello)首先,客户端(通常是浏览器)先向服务器发送加密请求,这一步叫做 1. 客户端支持的协议版本(这是为了和服务器协商使用什么版本的SSL/TLS进行通信) 2. 客户端生成的一个随机数n1 3. 客户端支持的加密方法,比如RSA(这是为了和服务器协商使用什么加密方法) 服务器响应(ServerHello)服务器收到客户端请求之后,向客户端发送响应,这一步叫做 1. 确认通信使用的SSL/TLS版本 2. 服务器生成的一个随机数n2 3. 服务器的数字证书 4. 确认加密方法,比如RSA 客户端回应客户端收到浏览器的响应后,首先验证服务器的证书时候有效。如果证书不是由权威结构颁发(比如12306),证书包含的域名和实际域名不一致或者证书已经过期,那么浏览器会警告用户,由用户决定是否继续访问。 如果证书没有问题,客户端便会从证书中取出服务器的公钥,然后发送一个请求,携带以下信息。 1. 一个随机数n3,这个随机数用服务器公钥加密,防止被窃听 2. 编码改变通知,表示之后所有的信息都将会使用双方商定的加密方法和密钥发送 3. 客户端握手结束通知,表示客户端的握手阶段已经结束 客户端此时有三个随机数,n1,n2,n3,根据这个三个随机数,客户端使用一定的算法生成通信所需的对话密钥。 服务器最后响应服务器收到客户端的随机数之后,使用私钥将其解密,这时,服务器也拥有了n1,n2,n3这三个随机数,服务器便可以生成和客户端一致的对话密钥。然后向客户端发送最后的响应。信息如下: 1. 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送 2. 服务器握手结束通知,表示服务器端的握手阶段已经结束 到了这里,客户端和服务器就可以使用对话密钥加密之后所有的通信过程。第三方无法窃听,都是乱码看不懂。也无法篡改,SSL使用MAC(Message authentication code)来校验信息。更无法冒充,因为没有对话密钥。 HTTPSHTTPS便是 证书从前面的描述中可以看出,要想进行SSL通信,服务器需要有一个权威机构认证的证书。证书是一个二进制文件,里面包含有一些信息(服务器的公钥,域名,有效时间等)。和域名一样,证书需要购买,并且价格不菲。下面是三个常用的购买证书的网站。 证书分为很多类型,首先分为三级认证:
除了三个级别以外,证书还分为三个覆盖范围:
很显然,认证级别越高,覆盖范围越广,证书价格越贵。好消息是,为了推广HTTPS协议,电子前哨基金会EFF成立了 Let’s Encrypt ,可以提供免费证书。So, Let’s Encrpyt~ Let’s Encrpyt这里,我使用一台新的 安装客户端先安装基础工具。 yum update
yum install -y git vim然后,我们来安装 git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt 最后,我们安装 firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https firewall-cmd --reload 将自己的域名配置到这台VPS上。这里,我使用 生成证书我们使用 默认的nginx配置不用任何修改,nginx默认的 cd /opt/letsencrypt ./letsencrypt-auto certonly -a webroot --webroot-path=/usr/share/nginx/html -d leaningmoon.io # 可以使用多个 -d 添加多个域名 回车之后,
最后,
可以看到,最为关键的证书文件存放在 配置nginx最后一步便是配置nginx采用我们的证书文件并开启https。这里推荐一个网站, cipherli.st ,这个网站提供了当前主流的web服务器怎样开启HTTPS的推荐配置。很值得参考。这里我们直接复制他提供的nginx配置。 server {
listen 80 default_server;
server_name leaningmoon.io;
return 301 https://$server_name$request_uri;
}
server {
# SSL Configuration
listen 443 ssl default_server;
root /usr/share/nginx/html;
# copy from https://cipherli.st
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Requires nginx >= 1.5.9
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
# specify cert files
ssl_certificate /etc/letsencrypt/live/leaningmoon.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/leaningmoon.io/privkey.pem;
}重启nginx,
参考链接 |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|