1. RSA算法
1.1. 特点
RSA的密钥分成两个部分:
-
PublicKey
- 加密数据
- 验证签名
- 不能解密
- 任何人都可以获得
-
Private Key
- 数据签名(摘要算法)
- 解密
- 加密(不用此功能)
- 不公开
RSA算法的特点:
- 公钥端到私钥端的通讯是安全的
- 因为只有私钥能解密
- 任何人都可以拿到公钥给私钥端发信息
- 私钥端给公钥端回消息不安全
- 私钥发的消息公钥可解密,任何人都可看到
- 私钥回的消息可以签名,保证无法被篡改
1.2. 生产中应用RSA算法
下文中的发消息可以理解为C/S中客户端,收消息和回消息理解为服务端。
单对RSA密钥适合场景:
- 单向发消息和收消息要求绝对安全
- 回消息要求不能被篡改,内容被别人看到也无所谓
以上满足以上特点的场景很少,更多时候希望通讯双方的所有数据都是加密的,并且都双方都可以解密,而且别人无法破解。这种时候可以使用对称加密,但是需要双方都配置好密钥就好了;如果使用RSA,只利用RSA发消息安全的特点,那么有两种方式:
方式一:两对RSA密钥
-
思路:两对RSA密钥,发消息时都用对方的公钥。
-
准备:双方各生成一对公钥和私钥,并把公钥给对方。
-
发消息:用对方的公钥把消息加密发给对方。
-
收消息:用自己的私钥解密消息。
-
回消息:类似发消息,用对方的公钥发送加密消息。
如果在Client-Server模型应用中使用这种方式步骤为:
- 服务端开放自己的公钥
- 客户端发送消息给服务端用服务端的公钥
- 客户端生成自己公钥和私钥,并把自己的公钥发给服务端
- 服务端回消息时候用客户端的私钥加密
这种方式是ssh免密登陆的实现,客户端接受服务端的公钥放到 ~/.ssh/known_hosts
,客户端再把自己的公钥配置到服务端的~/.ssh/authorized_keys
,这样就实现了双向加密通讯。
方式二:RSA+对称加密
- 思路:公钥端发消息时候,对消息再进行一次对称加密并把密码发给私钥端,后续对称加密通讯
- 准备:只要收消息一端有RSA密钥对,发消息一端不需要有自己的密钥对
- 发消息:公钥端把数据对称加密,然后把加密结果和对称加密的密钥用公钥加密,一起发给私钥端
- 收消息:私钥解密后拿到对称密钥和报文,再对报文解密得到明文
- 回消息:回消息只对称加密数据然后签名,公钥端先验签再用公钥解密
方式二https协议使用方案,也是ssh协议非免密的实现方案。
2. HTTPS协议
http是应用层协议,在tcp协议之上。这两个协议传输的都是明文,tcp之上再加一层安全协议SSL(Security Socket Layer) ,基于这一层实现http得到的就是https。
SSL是安全套接字编程接口,后来又进化为TLS(Transport Layer Security)传输层安全,定位类似,都是给TCP协议加密的。不管SSL和TLS都是软件实现的协议,在TCP/IP 4层模型中,它们也是应用层的。
在上一章,我们知道https同时利用了rsa和对称加密方法,通讯流程为:
-
步骤1:客户端请求服务端的证书
- 这一步被拦截、篡改了也没问题,因为只是通讯前的准备工作
-
步骤2:服务端给客户端发送证书
- 客户端收到证书后验真,如果OK,就有服务端的公钥了
- 证书是公开的,被拦截了也没问题
- 如果被篡改成假证书,并且客户端验证通过就不安全了
- 客户端用假证书的公钥加密并发送,被拦截后可以被跟假公钥配对的私钥破解
- 证书必须由专业结构(CA)发放
- 发放机构对证书所有者审核
- 如果使用假证书破解就可以根据家假证书找到破解者
-
步骤3:客户端生成对称密钥并用公钥发送给服务端
- 客户端记录下来生成的密钥
-
步骤4:服务端解析出对称密钥并存储
-
步骤5:客户端使用对称密钥加密数据发送
-
步骤6:服务端使用对称密钥解密数据,并把响应数据用对称密钥加密
rsa的主要作用:
- 客户端与服务器之间约定对称密钥
对称加密的作用:
- http报文安全传输
SSL证书包含的信息:
- 证书的发布机构CA(Certificate Authoritie)
- 证书的有效期
- 公钥
- 证书所有者
- 签名
证书最主要的作用就是存储服务器的公钥,并且保证服务器的的公钥是安全有效的,整个https安全的核心也是基于证书发放机构绝对安全。如果客户端拿着一个假的证书用了一个假的rsa 公钥,并且加密了发送,那这个假的公钥所对应的私钥就可以解密数据了。证书的真假只有靠证书的发放结构去验证,选择一家靠谱的发布机构很重要。
3. 使用
服务端
因为服务端要接受并解密数据,服务端要有rsa的公钥和私钥,对称加密的密钥是客户端动态生成的,所以我们生成一对密钥然后放到一个支持https的服务器上就完成了部署。
具体操作请参考 :
https://aotu.io/notes/2016/08/16/nginx-https/index.html
客户端
客户端要有接受服务端证书并验证证书的能力,但是如果我们的网络是内网部署就没法验证服务端发送过来的证书了。那可以预先把证书放到客户端,如果服务器发来的证书是我们信任的,那么就可以给它发对称密钥并通信。
具体操作请参考:
https://www.cnblogs.com/duanxz/p/5146340.html