在基于TCP长连接的CS链路中,如何保证数据流的安全性是开发者最关注的问题之一。本文深入浅出的给大家介绍一下在TCP连接中,使用RSA协商加密的方式,建立一个安全加密的通信链路,保证数据传输的安全性。文章分为3个主要部分,即RSA算法简介,安全信道协商流程详解和一些工程优化方法。期望大家在读了我这篇文章之后能够透彻的理解基于RSA协商加密方式的信道建立方式并能够运用在自己的业务实践中。

RSA算法简介

加密算法是计算机通信安全的基石,加密算法分为2个大类,即”对称加密算法“和”非对称加密算法“。”对称加密算法“的缺点比较明显,即甲方必须把加密规则告诉乙方,否则无法解密。因此保存和传递密钥,就成了最头疼的问题。本文所依赖的加密算法RSA算法是一种”非对称加密算法“,其具有以下特点:

  1. 乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的
  2. 甲方获取乙方的公钥,然后用它对信息加密。
  3. 乙方得到加密后的信息,用私钥解密。

其实关键知识点就是:用公钥加密,用私钥解密,私钥要做好保密
RSA算法的原理可以参照阮一峰的博文:http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.htmlhttp://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html

安全信道协商流程

我们选择使用RSA加密算法建立安全信道,在介绍具体方法之前,我们先约定几个术语:

  • C表示客户端(Client)
  • S表示服务端(Server)
  • priKey表示私钥(PrivateKey)
  • pubKey表示公钥(PublicKey)

下面分步骤对流程进行详细描述。

前提说明

在安全信道建立之前,客户端和服务端已经拥有一套公私钥对,公钥由客户端持有,私钥由服务端持有。这里的公私钥分别表示为:pubKey0和priKey0.

C->S传递pubKey

  1. 客户端生成一对公私钥,分别表示为pubKeyC和priKeyC,其中priKeyC客户端自己持有,pubKeyC需要传递给服务端;
  2. 客户端使用pubKey0对pubKeyC进行加密,然后通过TCP链路将加密后的数据传输给服务端;(这个过程我们称为Stage1)
  3. 服务端收到客户端加密的信息后,使用priKey0对信息进行解密,得到pubKeyC.

S->C传递pubKey

  1. 服务端生成一对公私钥,分别表示为pubKeyS和priKeyS,其中priKeyS服务端自己持有,pubKeyS需要传递给客户端;
  2. 服务端使用pubKeyC对pubKeyS进行加密,然后通过TCP链路将加密后的数据传输给客户端;(这个过程我们称为Stage3)
  3. 客户端收到服务端加密的信息后,使用priKeyC对信息进行解密,得到pubKeyS.

加密通信

经过上述全双工的加密协商过程,客户端和服务端之间就建立了使用RSA算法进行加密的通信信道,后续的数据传输就是在上述安全信道下进行的。具体如下:

  1. C-->S的数据,在C端加密,在S端解密,使用的是由服务端初始化生成的公私钥对(pubKeyS和priKeyS);
  2. S-->C的数据,在S端加密,在C端解密,使用的是由客户端初始化生成的公私钥对(pubKeyC和priKeyC).

工程实践中的一些优化点

尽量降低初始化私钥priKey0泄漏风险

上述公私钥协商过程的安全性是建立在初始化私钥,即服务端所持有的priKey0未泄漏的基础上的。如果priKey0泄漏了,那么理论上这个”安全“信道就不安全了。一般工程实践中,会通过2中方式去尽量降低私钥泄漏风险:

  • 将初始化公私钥对从一对扩展到多对,在Stage1的过程中,选择某一个公钥对数据进行加密,同时将公钥索引追加到传递给服务端的信息中去。服务端在收到信息后先解析出索引,然后取出对应的私钥进行解密;
  • 不定期的更新公私钥对,这种方案会有一定的弊端,服务端需要同时维护针对不同客户端版本的私钥信息,并且还要额外增加一个字段标识服务端使用那对私钥进行解密,不过可以通过控制客户端版本数量的方式,将维护成本降低,如维护2个版本客户端,其他版本强制退出。

服务端Stage3初始化公私钥性能

对于客户端来说,每次建立安全通道,单个客户端只需要进行一次公私钥对的初始化计算,性能不是瓶颈。但是,对于服务端来说,尤其是接入层,服务了众多TCP长连接,如果频繁的进行公私钥对的初始化计算,CPU性能的消耗成本是巨大的。所以一般工程实践中,会选择一种更为理性的方案。
具体做法可以是:

  1. 在服务端启动的时候,预先初始化多对公私钥对,如可以初始化128对或者更多,然后将这些公私钥对保存在内存中。
  2. 在Stage3阶段,服务端不即时生成公私钥对,只需要随机选择一个内存中的一对公私钥,并进行加密操作,将对应的公钥传递给客户端即可。

以上,就是本文的所有内容,期望大家看了之后能有所收获,谢谢大家!

posted @ 2018-09-19 10:27 薛定谔の喵 阅读(1626) 评论(0) 推荐(0) 编辑
摘要: robotframework是nokia提供的开源自动化测试框架,支持通过python、java等语言进行扩展,是自动化测试中使用比较多的,本文主要介绍该框架在windows系统的安装,并给出一个senium实例。 阅读全文
posted @ 2018-02-02 10:57 薛定谔の喵 阅读(401) 评论(0) 推荐(0) 编辑
摘要: 面对业务性能要求,pb序列化性能不符合预期,该如何优化?本文结合项目实战中遇到的性能问题,浅谈pb优化之路~ 阅读全文
posted @ 2017-06-10 19:01 薛定谔の喵 阅读(2058) 评论(0) 推荐(1) 编辑
摘要: 高并发网络服务器如何提高并发能力,单靠多线程是不行的,需要借助多路IO复用技术,提高并发能力。select和epoll是linux系统中常用的两种IO复用技术,当然,epoll是现在的主流技术,为什么epoll能够几乎代替select成为主流,让我们一探究竟! 阅读全文
posted @ 2015-12-23 17:48 薛定谔の喵 阅读(779) 评论(0) 推荐(0) 编辑
摘要: 让我们回到2014年11月,从公司请假回成都,在天府软件园B区旁边的小区里,那个10多平米的出租屋里,闲来无事,我想找个事情做一做,好让我这漂浮的心静下来。大约在半年前就申请了微信的一个公众账号,一直闲置着,终于决定再次着手搭建一个微信公众账号。SAE(Sina App Engine)是国内最早开始提供云服务的平台之一,而且几乎是免费的。所以希望能够通过SAE平台快速的搭建好一个微信公众账号,花了小半天就搭好了一个简易的微信公众平台。今天,就利用SAE搭建微信公众平台的过程和大家一起分享。 阅读全文
posted @ 2015-04-15 19:42 薛定谔の喵 阅读(1873) 评论(7) 推荐(2) 编辑
摘要: 在某些情况下,我们设计中的对象只需要一个,比方说:线程池(threadpool)、缓存(cache)、对话框、处理偏好设置和注册表对象、日志对象、充当打印机、显卡等设备的驱动程序的对象等。事实上,这类对象只能有一个实例,如果制造出多个实例,就会导致许多问题产生。 这里要说的单件模式就能确保一个类只有一个实例,并提供一个全局访问点。 阅读全文
posted @ 2015-03-27 16:34 薛定谔の喵 阅读(1648) 评论(2) 推荐(1) 编辑
摘要: Redis 是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 阅读全文
posted @ 2014-10-11 15:53 薛定谔の喵 阅读(2621) 评论(0) 推荐(1) 编辑
摘要: linux下调试你的C/C++程序,gdb是最常用的工具,本文就最常用的命令给大家提供一个list. 阅读全文
posted @ 2014-09-08 19:46 薛定谔の喵 阅读(3348) 评论(0) 推荐(1) 编辑
摘要: Protocol buffers是google提供的一种将结构化数据进行序列化和反序列化的方法,其优点是语言中立,平台中立,可扩展性好,目前在google内部大量用于数据存储,通讯协议等方面。PB在功能上类似XML,但是序列化后的数据更小,解析更快,使用上更简单。用户只要按照proto语法在.proto文件中定义好数据的结构,就可以使用PB提供的工具(protoc)自动生成处理数据的代码,使用这些代码就能在程序中方便的通过各种数据流读写数据。PB目前支持Java, C++和Python3种语言。另外,PB还提供了很好的向后兼容,即旧版本的程序可以正常处理新版本的数据,新版本的程序也能正常处理旧版本的数据。 阅读全文
posted @ 2014-08-19 14:44 薛定谔の喵 阅读(10666) 评论(3) 推荐(0) 编辑
摘要: 最近百度Hi项目拟针对内部员工版本增加设备绑定功能,也许是公司出于对员工聊天信息安全性的考虑,同时也考虑到后期会有相应的员工名片等功能的推出,设备绑定的过程也是为了员工名片功能做个准备吧!设备绑定的服务是用php语言实现的,我的主要工作就是在现有的平台上搭建好这个新的服务,然后测试各个接口,保证功能的可用性和性能等。我比较擅长的语言是C++和Python,Java和php基本处于听过、看过,没有写过的这种程度。我在搭建好测试环境之后,开始思考到底怎么去完成这件事?对于这种web请求,或许Java是最好的选择,C++太费事,Python也还是可以,但这个服务都是php提供的,用php去做这件事情也是个不错的选择。就是上个周末,周末闲来无聊,我就想看公司最近内推的邮件中对php开发的需求蛮多的,我是不是该学学php呢,然后我就开在linux下搭建了一个php开发环境,花了1天的时间看php cookbook的大概1/3左右。然后这周就遇到php的需求,所以当时就很愉快的做了一个决定,就用php了,正好验收下我上周末的学习情况。phpunit是php语言中的单测框架,就用它了,bingo! 阅读全文
posted @ 2014-08-10 10:59 薛定谔の喵 阅读(2600) 评论(0) 推荐(2) 编辑
摘要: 2014年6月4日,6月的第一个星期三,我正式入职百度,开始baiduer的工作。这不到2个月的时间,因为人力资源这边原因,我从INF部门离开,拉到了百度Hi-Server团队中来。2个完全不着调的岗位,做了许多以前没有做过的事情。总结一下:在INF的产品线是新产品,9月才百度世界大会才上线的,很多东西不便透露;百度Hi-Server产品线相对来说就算是个老产品了,持续做了好几年了。7月份切到Hi-Server这边,不到这一个月的时间,主要Support了三个事情:一个登录桩的实现和一个公众平台iOS消息推送,还有消息报文协议的单测。今天主要和大家分享一下登陆桩实现中遇到的一些问题! 阅读全文
posted @ 2014-08-01 12:49 薛定谔の喵 阅读(2259) 评论(0) 推荐(0) 编辑
摘要: 在Python中,标准库中提供了用于定时的执行某个任务的模块,即sched和Timer类。先说sched模块,准确的说,它是一个调度(延时处理机制),每次想要定时执行某任务都必须写入一个调度。 阅读全文
posted @ 2014-03-17 11:52 薛定谔の喵 阅读(4503) 评论(2) 推荐(0) 编辑
摘要: 最近申请到SmartWeatherAPI天气预报接口的使用权限,开始着手我的实时天气预报系统的开发,主要开发的版本使用的是Python脚本,成果将于近期以系列文章与大家见面。今天在这里我和大家探讨一下SmartWeatherAPI中key的计算方法,并提供C++程序源码供大家参考。 阅读全文
posted @ 2014-01-24 13:09 薛定谔の喵 阅读(9684) 评论(9) 推荐(1) 编辑
摘要: 大概半月前写了一篇博文:C++中使用Curl和JsonCpp调用有道翻译API实现在线翻译, 得到大家的热情捧场,有人看了文章说要是能发声不是更好,我觉得说的也是哈,能听到专家的标准发音,那该是多美的一件事,那我就研究下呗。这段时间一直在忙着学习Unix Network Programming的东西,终于在今天下午抽出时间来完成这个事情。今天,带给大家一个简易的发声辞典! 阅读全文
posted @ 2014-01-23 16:15 薛定谔の喵 阅读(4393) 评论(2) 推荐(1) 编辑
摘要: 所谓测试驱动开发,英文全称Test-Driven Development,简称TDD,是一种不同于传统软件开发流程的新型的开发方法。就是在明确要开发某个功能后,首先思考如何对这个功能进行测试,并完成测试代码的编写,然后编写相关的代码满足这些测试用例。然后循环进行添加其他功能,直到完成全部功能的开发。在本系列文章中,我将给大家介绍CPP的TDD编程中要用到的系列三方库,并给出配置过程和实例,感兴趣的猿们一起学习。 阅读全文
posted @ 2014-01-14 11:31 薛定谔の喵 阅读(2656) 评论(0) 推荐(0) 编辑
摘要: 使用C++开发一个在线翻译工具,这个想法在我大脑中过了好几遍了,所以就搜了下资料,得知网络上有很多翻译API,这里我选择我平时使用较多的有道翻译API进行在线翻译工具开发的练习。翻译API返回的结果常见的有两种:xml和json格式,本文选择使用json数据来实现Berlin版本的在线翻译工具。 阅读全文
posted @ 2014-01-10 22:04 薛定谔の喵 阅读(5860) 评论(9) 推荐(4) 编辑
摘要: 所谓测试驱动开发,英文全称Test-Driven Development,简称TDD,是一种不同于传统软件开发流程的新型的开发方法。就是在明确要开发某个功能后,首先思考如何对这个功能进行测试,并完成测试代码的编写,然后编写相关的代码满足这些测试用例。然后循环进行添加其他功能,直到完成全部功能的开发。在本系列文章中,我将给大家介绍CPP的TDD编程中要用到的系列三方库,并给出配置过程和实例,感兴趣的猿们一起学习。 阅读全文
posted @ 2014-01-10 13:29 薛定谔の喵 阅读(5522) 评论(1) 推荐(0) 编辑
摘要: 在Linux下使用C语言管理mysql数据库,从环境的搭建,demo的实现到编译运行,这不是太难的一个过程,但对于新手来说,还是难免走许多弯路,文章就配置过程,程序编写过程做个详细的记录,同时给出一个C语言代码mysql管理的小demo。 阅读全文
posted @ 2013-12-19 16:07 薛定谔の喵 阅读(1231) 评论(1) 推荐(2) 编辑
摘要: 对Python语言来讲,其单元测试的利器是PyUnit。Python 2.1及其以后的版本都将PyUnit作为一个标准模块。需要使用Python单元测试的猿们看过来! 阅读全文
posted @ 2013-11-12 09:55 薛定谔の喵 阅读(4449) 评论(0) 推荐(1) 编辑
摘要: 找工作是毕业生们的必经之路,无数次的被鄙视,无数次的爬起来,就是这个过程,让人体验成长!一起加油吧! 阅读全文
posted @ 2013-10-18 21:22 薛定谔の喵 阅读(6784) 评论(34) 推荐(7) 编辑
摘要: 你想复制一个对象?在Python中,无论你把对象做为参数传递,做为函数返回值,都是引用传递的。引用传递的意思就是说你传递的是对象的引用,对这个引用的修改也会导致原有对象的改变。学过C/C++的朋友们都知道,在交换2个数的时候,如果自己实现一个swap函数,需要传递其引用或者指针。Python直接使用引用传递,多方便啊,你还要吐槽什么?你又想过我不想改变原对象的情况吗?如果有,那么看这里! 阅读全文
posted @ 2013-10-15 14:19 薛定谔の喵 阅读(1136) 评论(1) 推荐(0) 编辑
摘要: 假设我们有这样一个集合set s;,然后我们向其插入10,s.insert(10);,然后再次插入10,我们知道对于set类型来说,是不能存在重复的数字的,插入元素的时候set中是如何判定有相同元素的呢?或许大家都没想过这个问题,今天我和大家一起去想一下! 阅读全文
posted @ 2013-10-06 00:09 薛定谔の喵 阅读(1056) 评论(0) 推荐(0) 编辑
摘要: C++中没有自动内存管理机制,所以内存的管理往往会考验一个程序员的编程水平。在C++11标准之前,在tr1命名空间中提供了几种智能指针,用于自动化管理内存。随着C++11标准的出炉,智能指针正式成了C++的标准之一,所以,是时候使用智能指针了。在我们平时学习,编程的过程中,一定要充分的利用这些特性。 阅读全文
posted @ 2013-10-05 14:58 薛定谔の喵 阅读(1126) 评论(2) 推荐(0) 编辑
摘要: 函数对象不是函数指针。但是,在程序代码中,它的调用方式与函数指针一样,后面加个括号就可以了。函数对象实质上是一个实现了operator()--括号操作符--的类。 函数对象与函数指针虽然定义不同,但是具有相同的使用方法。之所以要用函数对象,原因在于函数对象可以携带附加数据,而指针就不行了! 阅读全文
posted @ 2013-10-04 20:50 薛定谔の喵 阅读(682) 评论(0) 推荐(0) 编辑
摘要: Effective STL是学习STL必看的一本好书,近期我重新翻一遍,对其中比较重要的章节做个读书笔记,希望能够和大家一起分享! 阅读全文
posted @ 2013-10-04 18:00 薛定谔の喵 阅读(1050) 评论(0) 推荐(0) 编辑
点击右上角即可分享
微信分享提示