1. 程式人生 > >即時通訊系統中實現聊天訊息加密,讓通訊更安全【低調贈送:C#開源即時通訊系統(支援廣域網)——GGTalk4.5 最新原始碼】

即時通訊系統中實現聊天訊息加密,讓通訊更安全【低調贈送:C#開源即時通訊系統(支援廣域網)——GGTalk4.5 最新原始碼】

  在即時通訊系統(IM)中,加密重要的通訊訊息,是一個常見的需求。尤其在一些政府部門的即時通訊軟體中(如稅務系統),對即時聊天訊息進行加密是非常重要的一個功能,因為談話中可能會涉及到機密的資料。我在最新的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類增加了加密元件的設定:

    private static Des3Encryption des3Encryption = new Des3Encryption("abcd1234"); // null;        
    /// <summary>
    /// 3DES加密。如果訊息不需要加密,則返回null。
    /// </summary>
    public static Des3Encryption Des3Encryption
    {
        get { return des3Encryption; }
    } 

     這裡有一個開關的功能,即可以開啟或關閉聊天訊息加密功能。如果將des3Encryption設定為null,就表示不啟用聊天訊息加密。

2.傳送聊天訊息

  在GG即時通訊系統中,聊天訊息有兩類,一類是1對1的聊天,另一類是群聊天。如果啟用了加密,兩類聊天訊息都需要做相應的處理,它們的流程是一樣的。

      在得到聊天內容後,先進行簡單的序列化,然後對序列化的結果進行3DES加密:(以1對1聊天的ChatForm視窗中的實現為例,原始碼的第866行)

    ChatBoxContent content = this.chatBoxSend.GetContent();  byte[] 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類。

      GG在客戶端本地也有儲存聊天記錄(使用Sqlite),與伺服器上資料庫中儲存的不一樣的是,本地儲存的是明文的。所以,在檢視聊天記錄時,要根據使用者選擇的是從本地檢視還是從伺服器檢視來決定是否需要對資料進行解密:(對應ChatRecordForm窗體,原始碼177行)

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

五.原始碼下載

       GGTalk即時通訊系統是可在廣域網部署執行的C#開源即時通訊系統,2013.8.7釋出V1.0版本,至今最新是4.5版本,關於GG更詳細的介紹,可以檢視 可在廣域網部署執行的QQ高仿版 -- GG2014總覽

1.GG服務端和PC端原始碼   

    (壓縮包中有 《部署說明.txt》 和 建立資料庫的指令碼 《GG2014.sql》)

2.GG安卓版原始碼

      自從GG4.4版本開始,GG增加了安卓版本,其執行介面截圖如下所示:

             

      

      若要測試,請先部署服務端,然後修改安卓原始碼中MainActivity中的伺服器的IP和埠(如下圖所示),並重新編譯生成apk。

 

     (若要和PC端聯合測試,請關閉PC端那邊的聊天訊息加密功能:將PC客戶端專案的GlobalResourceManager類的 des3Encryption 成員賦值為 null 即可!)

注:GG安卓版的原始碼質量不是很高,屬於安卓初學者水平,很多地方有待改進,目前只是展示與PC打通的功能如何實現。若要將GG安卓版本的原始碼用於正式專案中,建議先對其進行重構。

相關推薦

即時通訊系統實現聊天訊息加密通訊安全低調贈送C#開源即時通訊系統支援廣域網——GGTalk4.5 最新原始碼

  在即時通訊系統(IM)中,加密重要的通訊訊息,是一個常見的需求。尤其在一些政府部門的即時通訊軟體中(如稅務系統),對即時聊天訊息進行加密是非常重要的一個功能,因為談話中可能會涉及到機密的資料。我在最新的GG 4.5中,增加了對即時聊天訊息進行加密的功能,但這一功能並不是強制的,可以通過開關來進行控制。本文

GGTalk即時通訊系統支援廣域網終於有移動端了!技術原理、實現原始碼

      首先要感謝大家一直以來對於GGTalk即時通訊系統的關注和支援!GGTalk即時通訊系統的不斷完善與大家的支援分不開! 從2013年最初的GG1.0開放原始碼以來,到後來陸續增加了網盤功能、遠端協助功能、離線檔案功能、群聊功能、語音聊天功能、視訊聊天功能、以及視訊錄製功能、和增加了資料庫——一路走

如何實現錄製視訊聊天的全過程? 低調贈送QQ高仿版GG 4.3 最新原始碼

  前段時間做個專案,客戶需要將視訊對話的整個過程錄製下來,這樣,以後就可以隨時觀看。想來錄製整個視訊聊天的過程這樣的功能應該是個比較常見的需求,比如,基於網路語音視訊的1:1的英語口語輔導,如果能將輔導的整個過程錄製下來生成一個標準的MP4檔案,就是一份難得的資料,便於以後複習和分享。我將1:1的視訊對話錄

QQ揭祕如何實現托盤閃動訊息提醒?低調贈送QQ高仿版GG 4.1 最新原始碼

  當QQ收到好友的訊息時,托盤的圖示會變成好友的頭像,並閃動起來,點選托盤,就會彈出與好友的聊天框,隨即,托盤恢復成QQ的圖示,不再閃動。當然,如果還有其它的好友的訊息沒有提取,托盤的圖示會變成另一個好友的圖示,並繼續閃動。那麼,QQ的這一效果是如何實現的了?我在QQ高仿GG2014中實現了同樣的效果,這裡

mp-redux解耦小程式的業務與檢視測試容易

專案地址:點我,歡迎star和issue mp-redux 一個用於小程式和輕量級H5應用的狀態管理工具, 使用方法是一個簡化版本的Redux。之所以是適用於輕量級應用,主要是因為沒有實現元件間的資料共享。因此不適合於複雜,龐大的前端應用。 是否你需要使用它? 如果你也和我有同樣的困惑,那麼你就該嘗試

QQ揭祕如何實現窗體靠邊隱藏?低調贈送QQ高仿版GG 4.2 最新原始碼

      QQ有個靠邊隱藏的功能,使用起來很方便:在螢幕上拖動QQ的主窗體,當窗體的上邊沿與螢幕的上邊沿對齊時,主窗體就會duang~~地隱藏起來,當將滑鼠移到螢幕上邊沿的對應區域時,主窗體又會duang~~顯示出來。   我在GG的最新版4.2中也增加了靠邊隱藏的功能,支援靠左邊沿隱藏、靠上邊沿隱藏、靠

無私分享ASP.NET CORE 專案實戰第二章新增EF上下文物件新增介面、實現類以及無處不在的依賴注入DI

目錄索引 簡介   上一章,我們介紹了安裝和新建控制器、檢視,這一章我們來建立個數據模型,並且新增介面和實現類。 新增EF上下文物件   按照我們以前的習慣,我們還是新建幾個資料夾   Commons:存放幫助類   Domians:資料模型   Services

Session 在分布式系統實現方式

同步問題 data- 操作 add cti ddc 技術 article sql數據庫 ##server獨立Session 例如以下圖所看到的: server獨立Session要求用戶的每次請求都必須在同一臺應用server上面操作,這就要求負載均衡

在Linux系統實現CA

linux、創建ca前言 CA是證書的簽發機構,它是PKI的核心。CA是負責簽發證書、認證證書、管理已頒發證書的機關。它要制定政策和具體步驟來驗證、識別用戶身份,並對用戶證書進行簽名,以確保證書持有者的身份和公鑰的擁有權。。 CA 也擁有一個證書(內含公鑰)和私鑰。網上的公眾用戶通

如何在springcloud分布式系統實現分布式鎖?

one 動作 分布式系 nil pan prism 培訓 多個 註釋 最近在看分布式鎖的資料,看了 Josial L的《Redis in Action》的分布式鎖的章節。實現思路是利用springcloud結合redis實現分布式鎖。 註意:這篇文章有問題,請看這一篇

python2實現sah-1加密

在java中實現對字串進行雜湊sah-1加密過程如下: public static String getExpandUserID(String UID) throws Exception { return "EU" + Base64.getEncoder().enco

在Android系統實現AIDL 自定義物件傳遞

  今天要在《在Android系統中實現AIDL介面回撥》這篇文章的基礎上實現AIDL自定義物件的傳遞功能。還是上一篇說到的三個專案: ├── SimpleJar ├── SimpleJarClient └── SimpleJarService 一、在SimpleJar專

Linux系統實現RAID卷詳解

   在Linux系統中做RAID,磁碟陣列的裝置可以是一塊磁碟中的三個以上的分割槽,也可以是三塊或以上的磁碟。本文主要以幾塊磁碟為例,來實現在RAID5。實驗環境:    系統中有一塊磁碟sda,新新增6塊SCSI磁碟,分別為sdb,sdc,sdd,sde,sdf,sdg

如何在springcloud分散式系統實現分散式鎖?

最近在看分散式鎖的資料,看了 Josial L的《Redis in Action》的分散式鎖的章節。實現思路是利用springcloud結合redis實現分散式鎖。 注意:這篇文章有問題,請看這一篇http://blog.csdn.net/forezp/art

在windows系統實現python3安裝lxml

lxml是Python中與XML及HTML相關功能中最豐富和最容易使用的庫。lxml並不是Python自帶的包,而是為libxml2和libxslt庫的一個Python化的繫結。它與眾不同的地方是它兼顧了這些庫的速度和功能完整性,以及純Python API的簡潔性,與大家

ZYNQ系統實現FAT32檔案系統的SD卡讀寫之三 SDK程式設計除錯

匯入到SDK後直接模板生成一個HELLO WORLD專案,之後在XILINX TOOLS-》BOARD SUPPORT PACKAGE SETTING裡面設定選擇XILFFS。 XILFFS各項可以設定引數按照預設,如下圖: 之後修改main函式所在檔案

在我的世界實現聊天框持續顯示人物座標

import mcpi.minecraft as minecraft#使程式可以呼叫minecraft的遊戲資源 import time#匯入了時間模組,以便控制以一定的時間間隔顯示座標 mc= minecraft.Minecraft.create()#使程式可

ZYNQ系統實現FAT32檔案系統的SD卡讀寫之四 經驗總結

在上述的三篇BLOG裡面主要介紹了步驟和設定,這裡簡答羅列一下此軟體硬體環境中進行FAT32讀寫的經驗總結。 1,SD卡要格式成FAT32格式。否則寫大檔案失敗,上幾M的就寫不了了。 2,每次建議寫256的整數倍位元組,否則餘數部分就會不能寫入,比如f_write函式

登入系統密碼用MD5加密有何作用?防誰呢?(附有程式碼)

在學習PHP100教程時,看到留言板的登入製作,先把MD5加密過的密碼形式儲存到資料庫中,然後通過登陸框輸入未加密的原始密碼,PHP從後臺幫你把原始密碼生成對應的MD5,再去和資料庫中的MD5密碼進行比對,比對一致則登入成功。我就在弱弱地想,這樣的MD5加密,為了防止誰呢?

Win10系統新增的快捷鍵做個記錄

png chm height col 視圖 分享 setting wid 記錄 Win10系統中新增的快捷鍵,做個記錄 1、Win+Q或者Win+S 打開下面搜索框 2、Win+T 切換任務欄上程序; 3、