APP下载

网络应用程序的安全研究与开发

2022-10-13刘文杰

网络安全技术与应用 2022年8期
关键词:服务器端序列化接收器

◆刘文杰

(荣成市教育教学研究中心 山东 264300)

在企业级局域网的应用场景中,经常需要开发CS架构的程序,这类程序的稳定性和安全性都是非常重要,服务器端的程序如果稳定性不强则容易崩溃,安全性不好则容易受到攻击。网络通信部分涉及的知识点多,开发难度高,并且需要进行长期的测试,普通的开发者很难独立开发,我们对一款国外的名称为Networkcomms开源的通信框架进行了深入的研究,这个通信框架面向微软.net平台,以开源形式基于Apache License v2协议发布,我们使用这个通信框架开发了多款产品,经过实践验证,这个通信框架性能突出,稳定性好,安全性高,值得深入研究。

1 CS架构程序的结构

CS架构的程序,分为客户端与服务器端,服务器端我们一般以Windows服务的形式部署在服务器上,客户端可以通过TCP协议与服务器端进行连接,程序的架构如图1。

图1 程序架构

2 数据的传输

客户端与服务器端之间的数据需要进行传输,数据的传输必须稳定高效,通过Networkcomms框架可以轻松的做到这一点,下面我们对框架的数据传输部分进行介绍。

2.1 数据的格式

数据通过TCP协议传输时,是以二进制的形式在网络上传输,我们在发送数据之前,需要按照一定的格式对数据进行封装,接收的一方收到数据后,按照预设的格式对数据进行解析。在Networkcomms通信框架中,数据包(Packet)的格式如下:

PacketHeader是数据包头,PacketData是数据包体,序列化之后的PacketHeader中的第一个字节,存放PacketHeader的数据长度,PacketHeader中的 TotalPayloadSize属性存放数据包体的数据长度,接收端的程序收到数据包(packet)后,首先根据第一个字节解析出PacketHeader的数据长度,根据数据长度接收数据,进而解析出PacketHeader,并根据PacketHeader中数据包体的数据长度接收数据,解析数据包体。

在.Networkcomms中,数据包头和数据包体的序列化方案有所不同,数据包头使用.net框架自带的BitConverter类对消息头进行序列化,没有使用第三方的序列化组件,数据包头通常不进行压缩,使用Networkcomms框架进行通信时,数据包包头常见的是40字节,所以一般没有对数据包头进行压缩的必要,如果压缩很小的数据反而会使数据变大,所以我们一般不压缩数据包包头。

数据包体支持多种序列化的方式,NetworkComms框架内置的序列化器有基于josn的JSONSerializer序列化器,基于谷歌序列化方案protobuf实现的ProtobufSerializer序列化器,也可以使用基于微软BinaryFormatter实现的二进制序列化器,通常我们使用最多的是ProtobufSerializer序列化器,也是Networkcomms推荐我们使用的序列化器。

图2 数据序列化器结构

我们在使用时可以非常方便的指定和切换序列化器,使用networkComms通信框架,在数据传递之前需要指定序列化器,我们可以进行统一的配置,不需要每次通信时都进行指定,指定默认序列化器的方式如下:

上面的代码中SendReceiveOptions是数据传输时存放相关收发数据参数的类,序列化器是参数中的一种,指定了网络通信时使用ProtobufSerializer作为序列化器。我们在编写程序时,服务器端与客户端的序列化器需要一致,否则不能正常的通信。

2.3 数据处理器

Networkcomms框架支持对数据进行压缩或者加密处理,这个主要依托数据处理器进行,内置的用于数据压缩的处理器有SharpZipLibCompressor,QuickLZCompressor,用于数据填充的处理器有DataPadder,DataPadder处理器支持填充随机数据,数据填充的目的是增加数据被截取后破译的难度。所有的数据处理器都继承自DataProcessor类。用户也可以根据需要实现自定义的数据处理器,自定义的数据处理器也需要继承自DataProcessor类。

图3 数据处理器结构

不同于数据的序列化,数据处理器在非必要的情况下,可以不使用。也可以根据需要同时使用多个数据处理器,比如即使用SharpZipLibCompressor数据处理器对数据进行压缩,也使用DataPadder数据处理器对数据进行填充。启动数据处理器需要在TCP连接之前进行配置,配置只需要通过简单的几行代码便可完成,如下:

通常在使用处理器时,客户端与服务器都需要配置相同的数据处理器来对数据进行处理。

2.4 数据流的线程安全

.net框架中用于数据传输的stream类并没有实现线程安全,而线程安全在很多时候是很重要的,能够确保程序的稳定性。Networkcomms框架对stream类进行了进一步的封装,创建了ThreadSafeStream类,ThreadSafeStream类继承自Stream类,扩展了该类的功能,并且解决了多线程访问时的数据流的安全问题。

2.5 SSL加密连接

在安全性要求较高的场景下,可以启用SSL加强数据的安全性。SSL也称为安全套接字协议,能够提升数据传输时的安全性,防止数据在传输时被截取。使用SSL传输数据,能够有效维护数据的完整性。Networkcomms框架创建了SSLTools类用于支持SSL。

2.6 对不规则数据启用拒绝服务攻击防护

拒绝服务攻击是一种常见的网络攻击方式,攻击者可以频繁的与服务器进行连接,消耗服务器的带宽和算力,对服务器端程序造成较大的影响,严重的情况下,可以使服务器无法提供正常的服务。

Networkcomms通信框架内置了应对拒绝服务攻击的方法,可以有效的应对拒绝服务攻击。当服务器端程序在监听端口上接收到的数据无法进行正常的解析时,可以判定为异常数据,通过DOSProtection类进行跟踪和处理。

当服务器收到异常数据,即收到不能正常解析的不规则的数据后,DOSProtection对相关数据的IP进行记录,默认如果在指定时间段内收到异常的连接请求超过100个,则对相应的IP地址进行查封。我们可对查封的时间长度进行设置,过了这段时间之后可自动解封。

3 文件的传输

使用Networkcomms通信框架,我们可以传送文件,既可以从客户端把文件发送到服务器端,也可以从服务器端把文件发送到客户端。小的文件可以一次性发送,大的文件一般需要分块发送,每一个文件发送时都会分配一个独特的文件ID,程序支持同时发送多个文件,客户端和服务器端都能够发送和接收文件。

图4 文件发送接收过程

3.1 文件发送

在文件发送时,首先使用FileIDCreator类为文件分配一个文件ID,这个文件ID是独一无二的,接收端在接收文件数据时,会把文件ID相同的数据派发给同一个文件接收器,文件接收器对数据进行组装。根据经验,文件分块的大小我们设置为40960字节,大于40960字节的文件,一般需要分块发送。文件发送部分我们设计了文件发送器和文件发送管理器以及显示文件传输进度的文件传输控件。

图5 文件发送架构

3.1.1 文件发送器

文件发送器主要用于发送文件,发送器根据文件地址在磁盘上找到文件生成FileStream文件流。然后把文件流封装成支持线程安全的ThreadSafeStream数据流。在文件发送器内对文件进行分块发送,每一个文件块都有一个“文件块顺序号”,接收端在组装文件时需要根据这个顺序号按照顺序组装文件。文件发送器在发送文件数据时,同时发送当前文件块的相关信息,相关信息主要包括文件ID、文件名、流的长度、发送的字节数、文件包的顺序号。服务器端收到这些数据后,将根据数据信息组装文件,显示接收进度,并把文件保存到相应的目录中。NetworkComms框架在发送消息时,数据包中带有消息类型,服务器端将会根据消息类型把消息分给不同的消息处理器进行处理。文件数据的消息类型为PartialFileData,文件信息的数据类型是PartialFileDataInfo。

文件发送器中定义了3个事件,分别是FileTransProgress(文件传输进度)、FileTransCompleted(文件传输完成)、FileTransDisruptted(文件传输中断)。这3个事件与文件传输窗体控件关联。每收到一个文件块,都会触发FileTransProgress事件,然后控件中的文件传输过程就会更新。如果文件传输完成或者文件传输中断,也会触发相应的事件,窗体控件中会有弹窗显示文件传输完成或者文件传输中断的信息。

3.1.2 文件发送管理器

每当发送一个新文件时,文件发送管理器都会创建一个文件发送器,其能够对文件发送器进行管理,文件发送完成后,相应的文件发送器会注销。文件发送管理器中有一个类型为 Dictionary<string,SendFile>的字典类,当有新文件开始发送时,文件ID作为关键词加入到字典类中。当某文件传输完成时,从字典类中删除该文件ID以及相关信息。可以根据文件ID在文件发送管理器中找到相应的文件发送器。文件发送器中的3个事件,即FileTransProgress(文件传输进度)、FileTransCompleted(文件传输完成)、FileTransDisruptted(文件传输中断)也会传递给文件发送管理器。

3.2 文件接收

相比于文件发送,文件接收会更加复杂一点,在文件接收端,需要对“PartialFileData”,“PartialFileDataInfo”这两种类型的消息进行处理,“PartialFileData”对应于文件数据,“PartialFileDataInfo”对应于文件信息。接收端接收文件时需要这2个消息都收齐后才能开始文件的接收。我们知道数据包的传输是有先后顺序的,接收端有可能先收到“PartialFileData”类型的数据包,也有可能先收到“PartialFileDataInfo”类型的数据包。NetworkComms框架在接收端设计了两个字典类型的容器用于缓存接收到的数据包。

当先收到文件数据,相应的文件信息还没有收到时,把文件数据加入到incomingDataCache容器中进行缓存,当先收到文件信息时,把文件信息加入到incomingDataInfoCache容器中进行缓存。加入相应的缓存容器时,都以文件的顺序号作为关键词。

如果文件数据和文件信息都已经收到,那么就可以启动文件接收管理器创建文件接收器开始接收文件。

文件接收与文件发送相对应,所以文件接收的实现与文件发送过程有类似的地方,文件接收部分的架构如图6。

图6 文件接收架构

3.2.1 文件接收管理器

文件接收管理器对所有需要接收的文件数据进行管理,为每一个需要接收的文件都创建一个文件接收器,把文件ID相同的文件数据都交给同一个文件处理器进行处理,如果两个文件数据的文件ID相同,说明这两个文件数据属于同一个文件,文件处理器将会根据收到的文件信息类进行组装即可。

文件接收管理器声明了4个事件,分别是FileTransProgress(文件传输进度)、FileTransCompleted(文件传输完成)、FileTransDisruptted(文件传输中断)、FileCancelRecv(主动取消文件传输)。文件接收管理器在创建文件接收器时会主动的关联文件接收器的相关事件。

如果文件接收完成,文件接收管理器会注销相关的文件接收器,这样能够节省资源。

3.2.2 文件接收器

文件接收器负责接收文件,文件接收管理器根据文件ID把属于同一个文件的数据派发给同一个文件处理器,所以每个文件接收器接收到的数据都属于同一个文件,文件接收器根据文件信息类进行组装即可,组装完成后,当前文件接收器注销。当有收文端接收到新文件后,文件接收管理器会创建新的文件接收器来接收新的文件。

文件接收器重新组装好文件之后,把文件保存在服务器上。

分块接收的代码如下:

3.3 文件传输控件

程序中的文件进行传输时,可以实时的显示文件传输进度,用户可以随时取消文件的发送,当文件传输完成时,弹出一个窗口显示文件发送完成,如果文件发送中断,也会弹出窗口显示,传输控件与文件发送器或文件接收器中的事件相关联,可以实时的显示出文件传输的进度,如果用户需要取消文件的发送或者接收,可以点击取消按钮进行取消。文件传输时的效果如图7。

图7 文件传输效果图

4 用户管理

当客户端与服务器端的TCP连接建立完成之后,客户端与服务器端就可以开始通信了,客户端可以发送数据给服务器端,也可以从服务器端获取数据。在一般的使用场景中,CS架构的程序的第一个窗体通常是用于输入用户名和密码的登录窗口,把用户输入的用户名和密码发送给服务器端,服务器端程序连接数据库,对客户端发来的用户名和密码进行验证,对不同角色的用户赋予不同的权限,并返回验证信息给客户端。

4.1 令牌认证机制(token)

客户端发送用户名和密码给服务器端,服务器端进行验证,如果验证成功返回一个消息给客户端,客户端接收服务器返回的验证消息,如果认证成功,程序跳转到主窗口,就可以在主窗口中同服务器进行通信了。对于简单的,对安全性要求不高的程序,这样是可以的。但存在一个问题,就是程序的客户端可能被反编译,攻击者可以直接修改登录窗体的代码,跳过用户验证这一步,直接进入到主窗体同服务器进行通信。为了解决这个问题,我们可以使用令牌认证机制。

具体做法是,客户端发送用户名和密码给服务器端,服务器端认证通过后,生成一串字符串作为令牌,并传递给客户端,客户端以后的每个请求都需要携带令牌信息。服务器端接收到消息后,首先解析出数据的类型,如果是请求登录的消息,则连接数据库进行认证,其他类型的消息都需要对消息携带的令牌消息进行认证,如果缺失令牌,或者令牌认证不通过,服务器端不返回消息给客户端,或者主动关闭与客户端的TCP连接。令牌具有时效性,如果客户端用户退出登录,或者客户端长时间没有请求消息,令牌都会失效,客户端再次请求数据时需要重新登录。

4.2 用户管理器

CS结构的程序,我们通常在服务器端实现一个用户管理器,用户管理器可以对所有在线用户进行管理。当用户认证成功后,服务器端把当前用户加入到在线用户管理器中。有了用户管理器的支持,不同的客户端之间可以进行端到端的聊天,服务器可以转发用户上线下线的消息给其他用户,服务器端可以主动发消息给选定的客户端,用户管理器我们用一个字典类实现,代码如下:

在企业级的场景中,我们经常需要开发cs架构的程序,开发这类程序,NetworkComms是一个成熟的通信框架,值得认真研究。研究这个框架的过程中可以学到很多的知识,特别是网络通信方面的知识,并对如何应对网络安全问题有更加深入的认识。

猜你喜欢

服务器端序列化接收器
浅谈一种新型的25Hz相敏轨道电路微电子接收器
奇奇小笨探秘海洋世界(六)
基于Qt的安全即时通讯软件服务器端设计
初中生写作序列化实践与思考
基于Qt的网络聊天软件服务器端设计
无线充电器
分层次序列化训练增强考场写作的增分因素
对“失序”的习作教学之思考和把脉
坚持以读促写 注重思维训练
一种基于Java的IM即时通讯软件的设计与实现