RSA与SSL浅析

HTTPS = HTTP + SSL

HTTP协议是明文传输的,也就是说当数据包使用HTTP协议进行传输的时候,如果数据包中途被截下来了,那么里面的数据(明文)就会完全暴露。因此,如果数据包里面存放着用户的帐号和密码,就可以认为用户的帐号和密码已经泄漏了。
HTTPS协议则使用了SSL对数据进行加密,即使数据被拦截下来,如果没有解密的密钥,也无法得知用户的数据。

RSA

RSA是一种非对称加密的算法,所谓非对称加密算法,就是用于加密解密的密钥有两个,即公钥和私钥,用公钥加密过的数据,只有私钥才能解密,用私钥加密过的数据,只有公钥才能解密。(对称加密算法就是说用于加密解密的只有一个密钥,密钥既能加密数据,又能解密数据)
公钥是可以公开的,别人知道也无所谓,私钥则要存储在安全的地方,不能泄漏。

考虑一下在客户端与服务器之间RSA的应用场景。

  • 客户端向服务器发送数据
    • 因为服务器的公钥是公开的,所以客户端很容易就能获取得到服务器的公钥。客户端利用服务器的公钥加密数据,这些数据只有存储在服务器的私钥才能解密。
  • 服务器向客户端发送数据
    • 服务器在向客户端发送数据的时候,除了用私钥加密以外,还要生成一个数字签名。
    • 什么是数字签名?服务器会使用hash函数对向客户端发送的数据生成一个摘要(digest),然后用服务器的私钥加密这一个digest,得到的就是数字签名了。
    • 当客户端拿到服务器发送的数据后,对数据使用相同的hash函数加密一遍,和用公钥解密的digest进行对比,如果核对一致则说明中途传输的数据没有被篡改。
  • 考虑第三种情况,如何确保你拿到的服务器公钥确实是正确的服务器的公钥呢? 即有人将其他的服务器的公钥给了客户端,使客户端误以为自己在跟正确的服务器进行交互。(攻击者可以在代理服务器层拦截客户端的请求,再重定向到自己的服务器)
    • 这时候我们需要一个权威的第三方机构(CA)确认这一个公钥确实是真实的服务器的公钥,服务器将自己的公钥和一些私人信息发给CA,CA用自己的私钥将这些数据加密之后就是数字证书(SSL证书)。
    • 当服务器向客户端发送数据的时候,还附带上从CA下载到本地的证书,客户端拿到证书以后使用CA的公钥进行解密,确认服务器的公钥无误。

客户端与服务器最终交互流程如下:
Https请求流程

RSA的运用场景:SSH

SSH远程登录主要有两种登录类型:口令登录以及密钥登录。

  • 口令登录
    • 客户端首先发出登录请求,服务器返回一个公钥,客户端使用公钥对登录密码进行加密,传输给服务器后,服务器使用私钥对登录密码解密然后核对。
  • 密钥登录
    • 客户端发出登录请求之后,服务器随机发送一段字符串,客户端使用自己的私钥加密之后返回给服务器,服务器使用存储的客户端的公钥进行解密,解密成功则登录成功。

有几点SSH文件放置注意的地方:

  • 客户端存放服务器公钥的地方在.ssh/known_hosts。
  • 服务器存放客户端公钥的地方在.ssh/authorized_keys。

如果使用密钥登录可以使用ssh-copy-id命令,不过要注意权限问题。

SSL

SSL是基于非对称加密的原理,在这之上还进行了对称加密的数据传输。当传送数据量过大的时候,客户端和服务器之间互相商定了一个对话密钥(session key),使用这个对话密钥来进行对称加密加快运算速度。

整个SSL的流程如下:

  • 客户端向服务器请求证书,验证无误后拿到服务器的公钥
  • 双方协商生成一个session key
  • 最后双方采用session key进行加密通信

主要关注前两步,即SSL的握手阶段。

  1. Client Hello
    • 客户端向服务器发出一个随机数,以及支持的传输协议以及加密算法 ,压缩方法。
  2. Server Hello
    • 服务器在确认支持客户端的传输协议等要求后,发送服务器的证书,以及一个随机数,安全需求更高的服务器会要求客户端发送证书来证明客户端的身份。
  3. 客户端回应
    • 客户端此时生成第三个随机数(这一个随机数被称为pre-master-key),向CA验证服务器的证书以后拿到服务器的公钥,使用公钥加密第三个随机数,并把加密后的第三个随机数发送给服务器。
    • 客户端在本地利用之前与服务器商量好的加密方法,根据这三个随机数生成一个对话密钥(session key)用于两端通信。
  4. 服务端回应
    • 服务端收到第三个随机数后,计算出对话密钥,至此,握手阶段结束。接下来使用对话密钥进行通信即可。

这里参考这篇博客中的一张表示SSL运行机制的图片:
SSL运行机制

SSL证书签名申请(CSR)

在购买了SSL证书以后,需要把证书和域名绑定起来。一般的证书是只能用在一个域名上,不过端口不限制。

如果希望子域名都能使用HTTPS可以考虑入手一个通配型的SSL证书,或者子域名个数不多的时候可以使用UCC类型的SSL证书。UCC类型的SSL证书是指一个证书可以加密指定数量的网站,在配置证书的时候往SAN里面添加额外的域名即可。

在服务器端使用openssl命令生成一个csr为后缀的文件(同时还有你的服务器私钥key文件),然后上传或者粘贴CSR文件内容至购买域名的网站:

openssl req -new -newkey rsa:2048 -nodes -keyout 您的域名.key -out 您的域名.csr
  •  

笔者购买的是GoDaddy的域名证书,该网站还提供了详细的Nginx的CSR配置文件指导,传送门如下:
生成 NGINX CSR(证书签名申请)

在提交CSR文件后CA会确认你是否拥有对这个域名的所有权,Godaddy提供了两种验证方法:

  • 首先,Godaddy会发送一封邮件,邮件里包含了要显示的指定内容。

    • 第一种方法 ,如果没有对域名的管理权,但是拥有域名映射到的服务器的所有权,将指定内容做成HTML文件,并上传至域名映射的服务器的根目录等待Godaddy确认。

    • 第二种方法,如果拥有对域名的管理权,则在域名解析里面添加TXT类型的DNS记录,记录值就为指定内容,等待Godaddy确认。

  • 域名所有权或者管理权验证完毕之后,即可下载SSL证书。

笔者在Godaddy下载证书之后得到两个证书(两个crt文件),其中有一个带有bundle命名的中间证书,需要把两个证书串联在一起得到一个最终证书。

$ cat first.crt bundle.crt > example.com.crt
  •  

Nginx配置HTTPS

非常简单,只需要在监听的端口上加上SSL配置就好了。

server {  
    listen 9999 ssl;
    server_name example.com;

    ssl on;
    ssl_certificate /root/.ssl/example_com.crt;
    ssl_certificate_key /root/.ssl/example_com.key;
}

参考资料:

猜你喜欢

转载自blog.csdn.net/liduanwh/article/details/81141881
RSA
SSL