HTML5技术

即时通信系统中如何实现:聊天消息加密,让通信更安全? 【低调赠送:QQ高仿版GG 4.5 最新源码】 - GG2014

字号+ 作者:H5之家 来源:H5之家 2016-01-20 17:03 我要评论( )

加密重要的通信消息,是一个常见的需求。在一些政府部门的即时通信软件中(如税务系统),对聊天消息进行加密是非常重要的一个功能,因为谈话中可能会涉及到机密的数据。我在最新的GG 4.5中,增加了对聊天消息进行加密的功能,但这一功能并不是强制的,可以

  加密重要的通信消息,是一个常见的需求。在一些政府部门的即时通信软件中(如税务系统),对聊天消息进行加密是非常重要的一个功能,因为谈话中可能会涉及到机密的数据。我在最新的GG 4.5中,增加了对聊天消息进行加密的功能,但这一功能并不是强制的,可以通过开关来进行控制。本文就从 为什么要加密消息、不加密有什么风险开始说起,一直到把GG即时通信系统中实现加密消息的完整实现介绍清楚。

一.为什么要加密消息?

  我们知道所有的消息在底层是以bytep[]进行传输的,如果文字聊天消息不加密,表示的意思是:直接将string使用utf-8或者unicode编码成byte[],然后,通过网络进行传送。如果在传送过程中的某个环节byte[]被恶意截取,则拦截者将byte[]使用utf-8或unicode进行解码,即可看到原来string的内容。这个过程如下图所示:

  

  对于某些重要的消息而言,这样明文传输的方式实在是太危险了。

  将聊天消息加密的意思是:将string使用utf-8或unicode编码成byte[]后,再做一次加密运算,得到一个新的byte[],然后将这个新的byte[]通过网络发送给对方;对方接收到byte[]后,先将其做解密运算,然后再用utf-8或unicode转为string。这个新过程如下图所示:

    

  这样,即使在网络传送过程中的某个环节byte[]被恶意截取了,拦截者也无法正确的解析它,如此就规避了原来方案的风险。

二.3DES加密

      3DES(或称为Triple DES)是非常常用的对称加密算法,是对DES算法的增强,它相当于是对每个数据块应用三次DES加密算法。

      在GG即时通信系统 4.5的客户端源码中,Des3Encryption类是实现3DES算法的类,我是根据3DES的算法原理实现的,可能与某些标准的3DES算法实现细节不一样,但是,使用其进行3DES加密、解密是完全能正常运作的。

   可以将Des3Encryption类作为一个工具类,从GG即时通信系统中抽离出来,复用在任何需要的地方。

三.加密/解密聊天消息

     现在我们正式回到GG即时通信系统的文字聊天逻辑上面来,看看GG是怎么实现聊天消息的加密解密的。    

1.准备工作

  GG2014客户端项目中,增加了Des3Encryption.cs文件,实现了3DES算法。

  GlobalResourceManager类增加了加密组件的设置:

des3Encryption = ); 3DES加密。如果消息不需要加密,则返回null。 Des3Encryption { get { return des3Encryption; } }

     这里有一个开关的功能,即可以开启或关闭聊天消息加密功能。如果将des3Encryption设置为null,就表示不启用聊天消息加密。

2.发送聊天消息

  在GG即时通信系统中,聊天消息有两类,一类是1对1的聊天,另一类是群聊天。如果启用了加密,两类聊天消息都需要做相应的处理,它们的流程是一样的。

      在得到聊天内容后,先进行简单的序列化,然后对序列化的结果进行3DES加密:(以1对1聊天的ChatForm窗口中的实现为例,源码的第866行)

[] buff = CompactPropertySerializer.Default.Serialize(content); byte[] encrypted = buff; if (GlobalResourceManager.Des3Encryption != null) { encrypted = GlobalResourceManager.Des3Encryption.Encrypt(buff); }

  然后,将加密的结果通过IRapidPassiveEngine发送出去。

3.处理接收到的聊天消息

     接收到1对1的聊天消息或是群聊天消息后,首先要做的是解密,然后再反序列化:(以1对1聊天消息的实现为例,MainFormPartial.cs文件中的源码的第37行)

byte[] decrypted = info; if (GlobalResourceManager.Des3Encryption != null) { decrypted = GlobalResourceManager.Des3Encryption.Decrypt(info); } ChatBoxContent content = CompactPropertySerializer.Default.Deserialize<ChatBoxContent>(decrypted, 0);

      之后,ChatBoxContent对象就可以在聊天窗中显示出来了。

4.处理离线消息

      离线消息是当接收者不再时,将该聊天消息暂存在服务器上,等接收者上线时,再发送给他。所以,离线消息的解密处理与普通聊天消息的处理是一样的。(MainFormPartial.cs文件中的源码的第86行)

if (informationType == InformationTypes.OfflineMessage) { byte[] bChatBoxContent = null; OfflineMessage msg = CompactPropertySerializer.Default.Deserialize<OfflineMessage>(info, 0); if (msg.InformationType == InformationTypes.Chat) //目前只处理离线的聊天消息 { sourceUserID = msg.SourceUserID; bChatBoxContent = msg.Information; byte[] decrypted = bChatBoxContent; if (GlobalResourceManager.Des3Encryption != null) { decrypted = GlobalResourceManager.Des3Encryption.Decrypt(bChatBoxContent); } ChatBoxContent content = CompactPropertySerializer.Default.Deserialize<ChatBoxContent>(decrypted, 0); } }

四.聊天记录要怎么处理了?   

      根据上面的流程描述,我们可以知道,在服务端看到的聊天消息是经过加密的,而GG在服务端有将聊天记录存储到数据库中的功能,因此,数据库中聊天内容那一列存储的数据也是加密的。

  在GG即时通信系统中,服务端不需要查看聊天消息的真正内容,所以,服务端不需要使用到Des3Encryption类。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 如何快速处理线上故障 - 倒骑的驴

    如何快速处理线上故障 - 倒骑的驴

    2017-05-02 12:01

  • 如何在 ASP.NET Core 中发送邮件 - Savorboard

    如何在 ASP.NET Core 中发送邮件 - Savorboard

    2017-05-02 08:02

  • 对于Bootstrap的介绍以及如何使用 - novai-L

    对于Bootstrap的介绍以及如何使用 - novai-L

    2017-04-29 09:00

  • 谈一下我们是如何开展code review的 - HarlanC

    谈一下我们是如何开展code review的 - HarlanC

    2017-04-27 15:03

网友点评
a