从HTTP到HTTPS协议系统升级总结

来源:互联网 发布:交换机端口速率配置 编辑:程序博客网 时间:2024/05/21 12:39

由于客户的一个安全性要求,需要把系统从HTTP升级到HTTPS协议,以前的系统是在B/S模式Websocket体系下进行实施的,并且所有的代码都是基于windows本身的IOCP(异步IO)的方式,在做项目之前本人Web端的小白一个,只懂一点C/S模式的socket,由于项目其他的人太忙了,而我又比较闲,然而就被赶鸭子上架了,于是就承担了整个系统的升级改造;经过了大约一个多星期的调查和设施,初步的了解了websocket, HTTP, HTTPS以及openssl的基本知识,便开始了初步的探索,废话不多说下面就从一个小白的角度来总结一下整个学习的过程,更多的还是以我曾经看过的博客说起。


一.Socket的再次认识

首先,我们项目的本身是基于websocket的windows自带的IOCP的方式实施的,为了实施HTTPS的升级,首先要了解什么是websocket,什么是HTTP, 以及它们和socket本身的区别:

http://blog.zengrong.net/post/2199.html

这篇博客讲述了上面的问题,我们知道socket是TCP/UDP协议的抽象,简化了我们对OSI模型实施的难度,它相当于一个API从而使网络以及串口通信都变得极为简单,可以说如果你想从事串口通信或者网络通信底层的通信技术,那么socket是你必须要掌握的一个重要的知识点;然而据我了解在windows系统下socket的本身是有两套体系(Linux只有一种即同步的方式),一种是同步方式,另一种是异步方式,所谓同步和异步,就是是否会发生IO阻塞,同步即是阻塞异步即是非阻塞,也就是当建立连接以及接收数据的时候是否需要等待;举个例子来说明第一种同步的发送数据方式:send(socket, oBuffer.GetBuffer(), dwToPick, 0); 而第二种异步发送的方式:WSASend(socket, &m_wsaOutBuffer, 1, &dwSent, ulFlags, &pWriteOverlap->m_ol, NULL);有一点要特别注意的是,如果你想让WSASend()函数采用异步方式,当你在建立socket套接字的时候必须要加上WSA_FLAG_OVERLAPPED,否则它就和send()函数没区别了,都是同步的方式,即 要写成hSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); WSASend()函数中pWriteOverlap->m_ol参数被称为是重叠IO和数据报消息,这个重要的参数将决定了异步通信时消息队列中消息的状态,然而不幸地是这个参数是由操作系统来改变,只有当数据发送完毕系统才会向消息队列发送完毕通知,这个消息程序员是没办法直接改变的,因此导致了我在给HTTP加openssl进行HTTPS升级时不得不彻底推翻整个系统,从新采用Boost.asio库来实施,当然如果你想挑战自己,我有一个很好的链接可能会帮助到你,这里提供了如何在windows系统中IOCP模式的socket下进行openssl的实施,并且里面附带了源代码,

http://www.serverframework.com/asynchronousevents/2010/10/using-openssl-with-asynchronous-sockets.html

只可惜笔者不才未能渗透其中的奥秘,而且由于以前系统基于IOCP模式十分多包括整个消息收发的机制都是与socket本身息息相关的,所以一番纠结过后还是晗着泪放弃了这个方法。


二.Websocket和HTTPS的初探

网上搜索了很多socket和websocket的区别,好多人都说它们俩毛关系没有,然而本人却并不这么认为,我喜欢按照自己的方式去理解,可能有误但很有效,对此引起对读者的误导在此声明概不负责!我的理解其实socket和websocket的区别不大,只不过前者是TCP的抽象更接近于底层会话层,而websocket更像是为Web端量身定制的一个更接近于应用层的协议,当然websocket的强大之处在于虽然它是HTML5的主要技术,然而它不仅仅只能应用Web还有很多方面;websocket将socket和Http协议的很好的整合了起来,从而它突破了html本身的弊端,即只能由客户端发起post,服务端响应的方式,websocket则是以全双工的方式通信,即连接建立后,客户端和服务端都可以主动发消息,并且它的另一大优点是很多浏览器都是支持的,可移植性更好数据交互流量会更少的特点,所以建议在网络通信时使用websockt协议。而HTTPS和HTTP的区别在于,HTTPS实际上是在HTTP协议上加了一个SSL层,从而保证了数据传输的安全,具体细节网上一大堆可以很容易的搜到,它最大的优势就是保障了数据传输的安全,毕竟安全第一嘛!然而HTTPS也有自己的弊端它的缺点就是由于需要加密等一系列繁琐的流程,因而它的传输速度比HTTP要慢,具体相差多大读者可以自己调查,笔者确实不太了解,另一个重要的因素,HTTPS需要第三方CA机构的证书认证,这将是一大笔费用,所以在项目中可以按照项目的情况而定。最后分享一个HTTP和HTTPS协议介绍的一个网址,内容可能比较多但很有趣。

http://www.cnblogs.com/zxj015/p/6530766.html


三.Openssl和Boost.asio的认识

由于需要进行HTTPS的升级,openssl便是最佳的实现SSL层的开源库,openssl是基于socket来实现SSL的,它是附着于socket上,在socket建立连接之后,绑定socket从而建立SSL会话空间,然后用SSL_write()以及SSL_read()来替换掉socket的recv()和send函数的;分享一个openssl简单实现服务端和客户端的两个网址,这里流程写的比较详细,而且有源代码!

CSDN:  http://blog.csdn.net/zqt520/article/details/8791130

博客园:  http://www.cnblogs.com/treecarrybear/p/6219769.html

可惜的是在windows IOCP模式下openssl没有与之对应的函数,网上有人说可以采用BIO的方式来实施,然而BIO本质上是SSL_xxx()系列函数的一个抽象,从它上面已经看不出socket本身的影子了,所以如果你的项目和我的一样socket消息部分应用的很多,那么恭喜你你没法使用BIO,如果你非要尝试,第一节中的那个链接将会对你有很大的帮助,而且stack overflow社区也有一部分这方面的信息,然而笔者尝试了很久,最终还是失败了,如果您在这个升级中成功了的话请务必告诉我,在下将感激不尽。由于上面所说的openssl在我的windows系统IOCP模式下配置失败,CTO给我的建议是扔掉原来的代码,转到Boost库上,重新搭建一个全新的HTTPS系统,然而本人对Boost.asio一窍不通,所以从零基础开始学习,如下是一个很好的Boost.asio学习的网站,与大家分享。

http://blog.csdn.net/zqt520/article/details/8791130

Boost库的特点是可移植性特别强,无论是windows还是Linux,使用它你可以很容易的实现移植,而且它的功能也十分强大,尤其对于异步编程来说更是不二之选,据说不久的将来它将会加入C++标准库中,笔者也很期待它的加入,通常异步编程都是基于消息队列来传递数据收发信号的,这种消息队列的实现起来十分复杂,没有十几年的工作经验很难处理恰当,而Boost库将这种消息机制封装了起来,以一种回调函数的方式巧妙的实现了消息的通知,当数据收发完毕后就会触发回调函数,从而进行后续处理。如果你采用C++11以及更高的版本,对于简单的回调函数,你可以使用lamda表达式来优雅的实现后续处理。Boost库还有很多其他的优雅而简洁的功能等着人们去发现。


四.Openssl实现自签证书

在我的项目中这是一道最大的坎,因为我的系统只是一个windows服务作为服务端,而客户端是websockt写的浏览器的网页,并且服务和浏览器是在同一台机器上的;如果你网上找服务器和证书相关的东西,一大堆的都是Nginx或是Linux服务器,证书都是Web网站的,必须要有公网IP或是域名,可是我的项目没有IP和域名啊,我的使用的一定要是本机地址啊,就是127.0.0.1或localhost所以去了好的能提供CA证书的网站咨询都拒绝提供自签证书,只能自己生成,所以刚开始生成的证书基本都是由于加密算法等级太低,被浏览器给拒绝了。。。,所以自签证书的时候,一定要弄明白你的证书的 加密算法是什么,还有你的签名地址一定要写对,我的项目的地址就是127.0.0.1,两者缺一都会被浏览器给拒绝了,然而你可能并不知道。。。,还有一定要会用openssl的工具进行证书的验证以及SSL通信的测试,否则证书这一关将会是你项目中很大的一道阻碍,分享一个比较详细的自签证书生成的网址,

http://www.linuxidc.com/Linux/2015-01/112071.htm

这里有比较详细的生成过程,当然还有一点要特别注意,要记得修改你的openssl.cnf文件否则按默认生成的证书,很可能就是因为加密算法简单而被浏览器拒绝,至于证书如何安装,你可以参照安装12306网站的证书同样的方式即可,还有至今我都没弄明白椭圆曲线(ECDHE类型的)加密算法的证书怎么生成,如何你知道的话,请告诉我一说,对此深表感谢。


五.服务端的配置

对于这一点,本人了解甚少,只能分享几个网址供大家去学习,这些网址都是我花了好久找到的,感觉是最好的,

1.服务配置博客,这个人的web端的博客特别棒:

https://imququ.com/post/troubleshooting-https.html

2.SSL测试,以及浏览器支持协议查询的网站,可以让你很好的了解你浏览器的属性:

https://www.ssllabs.com/projects/index.html

3.服务端加密算法(cipher suite list)以及其他推荐设置的网站:

https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations

4.github中一个很好的利用boost.asio实现HTTP以及HTTPS的项目:

https://github.com/eidheim/Simple-WebSocket-Server


最后,建议大家项目中最好使用Google而不是百度,虽然我也是支持国产但是说句实话百度的搜索结果真心不如Google,如果你上不了Google那就偷偷的下一个翻墙软件吧;只有你想不到的没有你搜不到的。

原创粉丝点击