tcp长连接的双向加密

一、历史和基础

做即时通讯项目,网游登录等业务时,我们通常需要一种能在线回推的机制,这时候客户端的tcp长连接就可能派上用场了。

示意图:

二、问题产生

曾经做过一个项目,之前老的加密方案为:

  • 1.客户端发一个rsa公钥G1给服务端(明文),自己留着S1
  • 2.服务端生成一个对称加密rc4秘钥,使用客户端的rsa公钥加密后发给客户端(明文)
  • 3.服务端发完秘钥后将tcp的接收和发送缓冲区加上rc4的对称加密层。
  • 4.客户端拿到服务端发回的G1加密的rc4秘钥,使用S1解密拿到rc4秘钥
  • 5.将tcp的接收和发送缓冲区加上rc4的对称加密层。

这样客户端和服务端之后的通讯将使用rc4的流加密方案。

这里有个问题,就是第一步,客户端发rsa公钥到服务端的时候是明文的。
这无法防范中间人攻击。

  • 1.中间人截取客户端发给服务端的rsa公钥G1。
  • 2.中间人生成一个新的rsa公钥G2,S2,并将G2发给服务端。
  • 3.服务端发G2加密的rc4秘钥M1给中间人
  • 4.中间人使用S2解密拿到rc4秘钥M1
  • 5.中间人将中间人到服务端的tcp的接收和发送缓冲区加上rc4的M1对称加密层。
  • 6.中间人生成新的rc4秘钥M2,并使用G1加密,发给客户端
  • 7.中间人将中间人到客户端的tcp的接收和发送缓冲区加上rc4的M2对称加密层。
  • 8.客户端拿到M2后使用M2加密tcp的接收和发送缓冲区

中间人获取了所有信息
图示:

三、参考和实例方案

看看https使用的证书的方式,而且会有一个根证书的认证过程。
但是通常我们做tcp长连接的时候没必要做这么复杂的流程
我们可以仿照https但是需将其简化

在说说通常的tcp长连接到网关的过程

  • 1.客户端向入口服获取网关的地址
  • 2.入口服选取一个可用的网关地址发给客户端
  • 3.客户端tcp长连网关服务

这里有个地方可以做点文章:

  • 1.网关服启动时,定期生成一对rsa秘钥G0,S0,并将公钥和地址公开
  • 2.当入口服选取一个网关地址发给客户端时,可以将网关服的公钥G0和tcp服务地址,一并发给客户端
  • 3.客户端生成一对rsa秘钥G1,S1,并且生成一半rc4秘钥ML,将ML使用G0将ML加密,最后将加密的ML和G1发给服务端
  • 4.服务端使用S0解出ML,服务端生成另一半rc4秘钥MR,将MR使用G1加密发回客户端。
  • 5.服务端将ML和MR拼成完整的rc4秘钥作为tcp的加密层
  • 6.客户端使用S1解出MR,与本地的ML拼合成完整的rc4秘钥作为tcp加密层。

图示:

中间人因为无法获取服务端动态生成的rsa私钥S0,而无法完成攻击。

客户端发送秘钥阶段,服务端发送秘钥阶段,在握手没有完成时,通过多服务联动方案,两阶段都使用rsa完成双向加密。

具体在做入口服和网关服同步公钥和地址时,我的方案:

  • 1.zookeeper的中间件,其中网关服务上传自己的地址和公钥G0,启动时生成一次,每隔一小时重新生成一对新的rsa秘钥
  • 2.入口服监听zookeeper,通过同步得到地址和公钥G0。
  • 3.客户端使用G0向网关握手失败时,再次向入口服拿取新的公钥和地址,即可解决一小时变更新rsa秘钥的延迟错误
  • 4.rc4的左半长和右半长使用编译期固定位(我用的16位)动态秘钥
  • 5.网关可以将负载信息做同步,方便入口服按照区域和负载做选取。
  • 6.网关服可以随需求做水平扩展,而不会影响之后的集群方案。
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值