Jack Jiang

          我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
          posts - 499, comments - 13, trackbacks - 0, articles - 1

               摘要: 本文由微信客戶端技術團隊工程師“Jon”分享,原題“Windows微信:消息數據庫架構演進”,有較多修訂。1、引言本文分享的是,微信客戶端團隊基于對微信用戶日常使用場景和數據分析,通過分離重要和非重要數據、采用可靠的分庫策略等,對微信Windows端IM本地數據庫的架構進行的優化和改造,并最終得到一個具備良好實踐效果的技術改造方案。 以下是...  閱讀全文

          posted @ 2022-09-05 11:50 Jack Jiang 閱讀(144) | 評論 (0)編輯 收藏

          本文由融云技術團隊分享,原題“互聯網通信安全之端到端加密技術”,內容有較多修訂和改動。

          1、引言

          在上篇《IM聊天系統安全手段之通信連接層加密技術》中,分享了關于通信連接層加密的相關技術和實踐,包括在傳輸即時通信消息時啟用 TLS 鏈路加密(保證消息在到達服務器前無法被竊聽和篡改)、使用 CA 認證機制(杜絕中間人攻擊)等。

          本篇將圍繞IM傳輸內容的安全問題,以實踐為基礎,為你分享即時通訊應用中的“端到端”加密技術。

          學習交流:

          本文已同步發布于:http://www.52im.net/thread-4026-1-1.html

          2、系列文章

          本文是IM通訊安全知識系列文章中的第11篇,此系列總目錄如下:

          3、為什么需要端到端加密?

          上篇中提到的連接層加密技術,這是提升IM客戶端到服務器之間數據傳輸的安全性手段,但是這并不能解決用戶間的通信隱私性以及安全性風險。

          因為在將數據傳輸到服務器之后,所有有權訪問此服務器的人,包括員工、供應商及其他有關人員(甚至黑客),都有可能讀取到用戶的數據。

          有鑒于此,端到端加密技術在即時通訊IM領域被廣泛應用,包括WhatsApp、Signal、Telegram 等國外即時通信軟件中都有使用。

          PS:有關端到端加密的基礎知識,可以從這兩篇里得到,建議詳讀:

          4、端到端加密的技術設計思路

          4.1 簡化版思路

          說到端到端加密,我們首先想到的解決方案是:在發送端發送消息前對整個消息進行加密,接收端接收到消息后進行解密。

          如上這樣:消息中轉服務器就無法獲取我們的消息內容了。

          事實上:這確實是端到端加密中消息收發的簡化版解決方案,只是我們在實際應用中要更加復雜,效果也更加安全。

          4.2 如何安全地傳遞用于消息加解密的密鑰

          對于端到端加密,我們需要先解決的前置安全問題是:如何安全地傳遞用于消息加解密的密鑰。

          答案是:用非對稱加密的方式傳輸密鑰(與 SSL / TLS 中安全交換密鑰的方式類似)。

          非對稱加密傳輸對稱加密密鑰的算法,一般歸結兩種方式:

          • 1)一種是以 RSA、ECC 等為主(公鑰加密私鑰解密的方式,本質是加解密的算法);
          • 2)另一種是以 DH、ECDH 為主的生成共享密鑰的方式(本質是通過計算協商一個共同的密鑰而不是加解密算法)。

          實際上:大部分即時通信軟件中的端到端加密都采用生成共享密鑰的方式來傳輸會話密鑰。這是為什么呢?

          這就涉及到 DH 算法(即 Diffie-Hellman 密鑰交換算法),關于DH算法的資料,有興趣可以詳讀《Diffie-Hellman密鑰協商算法》,限于篇幅,這里不專門討論。

          Diffie-Hellman 密鑰交換算法的安全性依賴于這樣一個事實:雖然計算以一個素數為模的指數相對容易,但計算離散對數卻很困難。對于大的素數,計算出離散對數幾乎是不可能的。

          這里簡要描述一下 DH 共享密鑰的過程如下:

          其中“密鑰 S”即為最終的共享密鑰

          4.3 采用共享密鑰的原因

          端到端加密采用共享密鑰的方式來傳輸會話密鑰有如下幾個原因:

          1)如果采用 RSA、ECC 等公鑰加密私鑰解密的方式傳輸密鑰,需要在創建會話時生成臨時密鑰,并通過對方公鑰加密后傳輸到接收端。

          這就需要完全保證消息的可靠性,如果該消息在任何一個環節中丟失或損壞,則后續通信都無法進行?;蛘?,需要采用更為可靠的傳輸方案,通常做法為需要接收端在線,通過各種確認來保證這個可靠性。

          而采用共享密鑰的方式則只需要知道對方的公鑰,就可以完成生成共享密鑰,并不一定需要對方在線。

          2)如果已經生成的臨時對稱密鑰丟失,則需要重新協商密鑰。而采用共享密鑰的方式則只需要知道對方的公鑰,就可以完成生成共享密鑰,不需要重新協商。

          3)采用公鑰加密私鑰解密的方式至少會比生成共享密鑰方式多一次交換對稱密鑰的通信過程。

          4)密鑰協商方式,不僅僅可以完成兩個點之間的密鑰協商,還可以延展到多人之間的共同協商出相同的密鑰,這樣能滿足多人群體溝通的需求。

          5、端到端加密的初步實踐方案

          我們結合對于 DH 算法(即 Diffie-Hellman 密鑰交換算法)這種共享密鑰方式的認知(即公鑰可隨意公開),先設計一個簡單的端到端消息加密的過程。

          這個過程的邏輯流程如下:

          • 1)在客戶端 APP 首次安裝時,基于服務器公開的兩個全局的參數,生成自己的 DH 公鑰和私鑰;
          • 2)將自己的公鑰上傳證書服務器,證書服務器上保存用戶標識與其公鑰的關系。私鑰則保存在客戶端上;
          • 3)首次給對方發送消息或首次接收到對方消息時,便到證書服務器查詢對方的公鑰;
          • 4)根據對方公鑰和自己的私鑰計算出共享密鑰;
          • 5)后續與對方所有的消息都基于這個密鑰和相同的對稱加解密算法進行加密解密操作。

          端到端消息加密過程示意:

          至此:我們完成了一個簡單的端到端消息加密方案,在這個方案中我們引入了一個第三方的用于存儲用戶公鑰的角色,這個角色的存在可以讓任何一方都不用關心對方的在線狀態,隨時給對方發送加密過消息,而消息轉發服務器無法解密消息。

          接下來,我們針對這個簡單方案存在的各種安全隱患問題,進行逐步分析和優化。

          6、端到端加密實踐方案的進一步優化和演進

          6.1 使用HMAC作為消息完整性認證算法

          在消息傳輸過程中,雙方需要確認彼此消息的完整性,簡單的做法就是將消息進行 Hash,得到的 Hash 值附加到消息后,隨消息一起發送;對端接收后,同樣進行 Hash,來驗證消息是否被篡改。

          關鍵點在于不同數據得到的 Hash 值一定不同,其中帶密鑰的 Hash 值就是 MAC算法。

          另外,為了避免使用同樣的 Hash 函數對相同數據進行操作總是得出同樣的值,額外加入一個密鑰,這樣使用不同密鑰就可以得出不同的 MAC。當然,這個密鑰是兩個對端都知道的。

          這樣,我們就得到了基于加密 Hash 的消息完整性認證的算法——Hash-based MAC(簡稱HMAC)。

          基礎知識1:什么是MAC算法?

          全稱Message Authentication Code,即消息認證碼(帶密鑰的Hash函數)。在密碼學中,MAC是通信實體雙方使用的一種驗證機制,是保證消息數據完整性的一種工具。

          MAC算法的安全性依賴于Hash函數,故也稱帶密鑰的Hash函數。消息認證碼是基于密鑰和消息摘要“hash”所獲得的一個值,可用于數據源發認證和完整性校驗。

          使用 MAC 驗證消息完整性的具體過程是:

          • 1)假設通信雙方 A 和 B 共享密鑰 K,A用消息認證碼算法將 K 和消息 M 計算出消息驗證碼 Mac,然后將 Mac 和 M 一起發送給 B;
          • 2)B 接收到 Mac 和 M 后,利用 M 和 K 計算出新的驗證碼 Mac*,若 Mac*和Mac 相等則驗證成功,證明消息未被篡改。

          由于攻擊者沒有密鑰 K,攻擊者修改了消息內容后無法計算出相應的消息驗證碼,因此 B 就能夠發現消息完整性遭到破壞。

          簡而言之就是:

          • 1)發送者通過MAC算法計算出消息的MAC值,并和消息一起發給收信者;
          • 2)收信者用同樣的MAC算法計算收到的消息的MAC值,并對比兩者。

          下圖是原理示意:

          基礎知識2:什么是HMAC算法?

          HMAC是MAC算法中的一種,其基于加密HASH算法實現。任何加密HASH, 比如MD5、SHA256等,都可以用來實現HMAC算法,其相應的算法稱為HMAC-MD5、HMAC-SHA256等。

          6.2 使用ECDH算法替換DH算法

          DH 算法是以離散對數的數學難題為基礎的,隨著計算機計算能力逐步增強,我們要不停地使用更大的數以增加破解難度,目前業界普遍認為至少需要使用 2048 位 DH 算法才具備更好的安全性。

          在此我們引入 ECDH 算法替換 DH 算法。ECDH 密鑰協商算法是 ECC 算法和 DH 密鑰交換原理結合使用。ECC 是建立在基于橢圓曲線的離散對數問題上的密碼體制。在相同破解難度下,ECC 具有更小長度的密鑰和更快的正向計算速度優勢。

          我們系統上的 ECDH 可以直接采用目前公開的 sepc256kl 和 Curve25519 曲線,而無需服務再提供公開大數參數。

          6.3 提升前向安全性

          在消息傳輸過程中,如果協商好的密鑰泄露了,就意味著所有信息都將暴露于風險之下。

          為了防止這種情況發生,我們需要每次加密使用的密鑰都與上一次不同,且不可以反向推導得出之前的密鑰。

          此處引入一個 Hash 算法:這個 Hash 算法可以通過輸入一個密鑰導出另外一個離散性更大的密鑰,每次發送消息時都是用上次的消息密鑰進行 Hash 運算得出本次密鑰,由于 Hash 算法具有單向不可逆的特性,因此就無法通過本次的密鑰推導之前的密鑰。

          從感觀上,這就像一個棘輪,棘輪就是一種特殊的齒輪,他只能往一個方向轉下去,而不能往回轉。

          我們先來感性認識一下棘輪:

          在技術上,做到"只能往一個方向轉下去,而不能往回轉",是達到前向安全的關鍵。這就保證了,如果某一輪的密鑰被破解出來,但前面的密鑰是無法計算出來的,也就是前面的消息無法被解密。

          6.4 同時保證前向安全和后向安全性

          出于極致的安全性要求,我們會同時考慮前向安全和后向安全。如何保證在某次通信中,被破解出來的密鑰,不能破解出之前的消息,而且在一定周期內,這個破解出來的密鑰將不會再起作用。

          介于此我們再引入另外一個棘輪來保證其向后的安全性。這就是大名鼎鼎的 Signal protocol 中的雙棘輪算法。

          Signal protocol 是真正的端到端的通訊加密協議,號稱是世界上最安全的通訊協議,任何第三方包括服務器都無法查看通訊內容。

          雙棘輪算法包含一個 KDF 棘輪和一個 DH 棘輪。

          KDF 全稱(Key derivation function) 密鑰導出函數,用于從一個原始的密鑰導出一個或多個密鑰。本質上就是 Hash 函數,通常用來將短密碼變成長密碼。另外 KDF 需要加“鹽”(salt),用于防彩虹表,出于 Hash 的特性,這個“鹽”的長度至少要大于 Hash 結果長度。

          KDF (原密鑰,鹽) = 導出密鑰

          KDF 棘輪就是運用 KDF 算法,設計出一種密鑰不斷變化的效果,流程如下:

          首先:將初始密鑰使用 KDF 算法導出新的密鑰,新密鑰被切成兩部分,前半部分作為下一次 KDF 計算的輸入,后半部分作為消息密鑰。

          每迭代一次(也可以說棘輪步進一次),就會生成新的消息密鑰。

          由于 KDF 算法的單向性,通過這條消息的密鑰無法倒推出上一條消息密鑰,這就保證了密鑰的前向安全。但是如果 KDF 中的鹽被掌握,那么它就可以按照這種算法計算出以后所有的消息密鑰。

          為了保證后向安全,就要設計一種方法,使每次迭代時引入的鹽是隨機的,從而保證每次的消息密鑰是不可以向后推算的。

          由前面介紹的 DH 算法得知:兩對密鑰對可以通過 DH 協議生成一個安全的協商密鑰,如果更換其中一個密鑰對,新的協商密鑰也會變化。

          根據這個方法:我們可以設計出一個安全更新鹽的方法。我們在證書服務器增加一個臨時公鑰證書,這個臨時證書是按照接收雙方標識構建的臨時公鑰對,即每個人的每個單人會話都具備一個臨時公鑰。每進行一個消息輪回,就更新一次己方的臨時公鑰,同時根據另外一方的臨時公鑰和己方的私鑰進行協商,并將協商出的密鑰作為鹽,使得 KDF 棘輪算法生成的消息密鑰具有后向安全性。

          在初始時我們無法預測出每個人所有的新二人會話:那么我們就可以規定創建新的二人會話時,發起方首先生成一個新的臨時 DH 公私鑰對,并向服務器上傳自己的臨時 DH 公鑰;其次發送方用接收方公布的長期公鑰與自己的臨時私鑰協商出密鑰作為消息加密的密鑰,對消息進行加密;最后接收方首次接收到消息后用自己的長期公鑰和發送方的臨時私鑰計算得出消息密鑰,并在首次回復消息時生成臨時公私鑰,同時上傳臨時公鑰。

          問題是:如果接收端不在線,而發送端每條消息都去更新己方的臨時公鑰證書,就會導致發出去的這些消息,在接收端上線并收取后無法被正常解密。

          為了解決這個問題,我們需要規定:只有在發出消息并得到對方回復后才更新臨時證書,若對方不回復消息則不去更新臨時證書。接收端能回復消息就表示其已經上線并接收完消息,這樣就可以保證離線消息或者消息亂序也可以被對方正常解析。這種方法就是雙棘輪算法中的另外一個 DH 棘輪。

          6.5 更安全的密鑰交換協議—— X3DH

          對比最初的方案,為了滿足消息的前向安全和后向安全,我們增加了雙棘輪算法,在原基礎方案上為每個人增加了一組會話級別臨時 DH 密鑰,每個人都擁有一個長期密鑰和一組臨時密鑰。

          但是:由于長期密鑰無法被更換,所以方案依然存在著安全隱患。

          因此:Signal protocol 設計了一種更為復雜和安全的 DH 密鑰交換過程,稱之為 X3DH(即 DH 協議的 3 倍擴展版)。

          在 X3DH 協議里,每個人都要創建 3 種密鑰對,分別如下:

          • 1)身份密鑰對(Identity Key Pair):一個長期的符合 DH 協議的密鑰對,用戶注冊時創建,與用戶身份綁定;
          • 2)已簽名的預共享密鑰(Signed Pre Key):一個中期的符合 DH 協議的密鑰對,用戶注冊時創建,由身份密鑰簽名,并定期進行輪換,此密鑰可能是為了保護身份密鑰不被泄露;
          • 3)一次性預共享密鑰(One-Time Pre Keys):一次性使用的 Curve25519 密鑰對隊列,安裝時生成,不足時補充。

          所有人都要將這 3 種密鑰對的公鑰上傳到服務器上,以便其他人發起會話時使用。

          假如 Alice 要給 Bob 發送消息,首先要和 Bob 確定消息密鑰,流程大致如下:

          • 1)Alice 要創建一個臨時密鑰對(ephemeral key),我們設成 EPK-A,此密鑰對是為了后面棘輪算法準備,在此處作用不大;
          • 2)Alice 從服務器獲取 Bob 的三種密鑰對的公鑰:身份密鑰對IPK-B、已簽名的預共享密鑰 SPK-B、一次性預共享密鑰 OPK-B;
          • 3)Alice 開始使用 DH 協議計算協商密鑰,要引入參數包括:自己創建的兩個密鑰對的私鑰,以及 Bob 的三個公鑰。然后用類似排列組合的方式,將自己的私鑰與對方的公鑰分別帶入 DH 算法計算。

          DH1 = DH(IPK-A, SPK-B)

          DH2 = DH(EPK-A, IPK-B)

          DH3 = DH(EPK-A, SPK-B)

          DH4 = DH(IPK-A, OPK-B)

          如圖所示:

          然后將計算得到的四個值,前后連接起來,就得到了初始密鑰,如下:

          DH = DH1 || DH2 || DH3 || DH4

          注:“||”代表連接符,比如 456 || 123 = 456123

          但是 DH 這個密鑰太長,不適合作為消息密鑰,所以對這個初始密鑰進行一次 KDF 計算,以衍生出固定長度的消息密鑰 S:

          S = KDF(DH1 || DH2 || DH3 || DH4)

          這一步,Alice 終于計算出了消息密鑰 S。

          于是:

          • 1)Alice 使用消息密鑰 S 對消息進行加密,連同自己的身份公鑰 IPK-A 和臨時公鑰 EPK-A 一同發給 Bob;
          • 2)Bob 收到 Alice 的信息后,取出 Alice 的 2 個公鑰,連同自己的密鑰,使用與 Alice 相同的算法計算消息密鑰 S;
          • 3)Bob 和 Alice 使用消息密鑰進行加密通訊。

          由上可知:X3DH 實際是復雜版的 DH 協議。

          至此:我們簡單介紹了 Signal Protocol 中最為核心的 X3DH 協議與雙棘輪算法,基本上可以滿足前向安全和后向安全。當然,真實的處理過程會更為復雜和安全。

          7、IM群聊的端到端加密方案

          在即時通訊場景中,除了二人之間的聊天以外,還有一個重要的場景就是群聊,那么群聊時的多人消息如何做端到端加密呢?

          我們再次回到 DH 密鑰協商算法上的推導過程:顯然,多方情況下依然可以繼續使用 DH 密鑰協商算法,這就是群聊中端到端加密的基礎。

          而 Signal Protocol 在群組聊天中的設計與二人聊天又有所不同,由于群聊的保密性要求相對低一些,只采用了 KDF 鏈棘輪+公鑰簽名來進行加密通訊以保障加密的前向安全。

          群組聊天的加解密通訊流程如下:

          • 1)每個群組成員都要首先生成隨機 32 字節的 KDF 鏈密鑰(Chain Key),用于生成消息密鑰,以保障消息密鑰的前向安全性,同時還要生成一個隨機 Curve25519 簽名密鑰對,用于消息簽名;
          • 2)每個群組成員用向其它成員單獨加密發送鏈密鑰(Chain Key)和簽名公鑰。此時每一個成員都擁有群內所有成員的鏈密鑰和簽名公鑰;
          • 3)當一名成員發送消息時,首先用 KDF 鏈棘輪算法生成的消息密鑰加密消息,然后使用私鑰簽名,再將消息發給服務器,由服務器發送給其它成員;
          • 4)其它成員收到加密消息后,首先使用發送人的簽名公鑰驗證,驗證成功后,使用相應的鏈密鑰生成消息密鑰,并用消息密鑰解密;
          • 5)當群組成員離開時,所有的群組成員都清除自己鏈密鑰和簽名公鑰并重新生成,再次單獨發給每一位成員。這樣操作,離開的成員就無法查看群組內的消息了。

          由上可知:一個人在不同的群組里,會生成不同的鏈密鑰和簽名密鑰對,以保障群組之間的隔離。在每個群組中,每個成員還要存儲其它成員的 KDF 鏈和簽名公鑰,如果群組成員過多,加解密運算量非常大,會影響發送和接收速度,同時密鑰管理數據庫也會非常大,讀取效率也會降低。

          所以:群組聊天使用 Signal Protocol 協議,群人數不宜太多。

          8、端到端加密方案的補充說明

          上面我們介紹了即時通信中二人聊天和群組聊天的端到端加密全部過程。但是正常情況下端到端消息加密只是加密消息的實際負載部分(即只加密消息“體”部分),而消息的控制層則不會被加密,因為消息轉發服務器需要根據控制信息進行消息轉發或路由(否則肯定大大影響IM底層的路由和通信效率,因為需要反復加密解密)。

          為了防止消息被定向分析(分析用戶什么時間向誰發送了消息,或接收了誰的消息),我們依然需要對整體即時通信的長連接鏈路進行加密保護(這說的就是上篇文章里的通信連接層加密技術了),防止信息被中間網絡設備截獲并分析。而且為了防止密鑰服務器被中間人攻擊,也需要開啟鏈路加密保護。

          9、參考資料

          [1] 移動端安全通信的利器——端到端加密(E2EE)技術詳解

          [2] 簡述實時音視頻聊天中端到端加密(E2EE)的工作原理

          [3] HASH、MAC、HMAC學習

          [4] 一文了解加解密、哈希函數、MAC、數字簽名、證書、CA等

          [5] 雙棘輪算法:端對端加密安全協議,原理以及流程詳解

          [6] Signal protocol 開源協議理解

          [7] X25519(Curve25519)橢圓曲線參考資料

          本文已同步發布于:http://www.52im.net/thread-4026-1-1.html

          posted @ 2022-08-29 16:13 Jack Jiang 閱讀(102) | 評論 (0)編輯 收藏

          本文由融云技術團隊分享,原題“互聯網通信安全之端到端加密技術”,內容有修訂和改動。

          1、引言

          隨著移動互聯網的普及,IM即時通訊類應用幾乎替代了傳統運營商的電話、短信等功能。得益于即時通訊技術的實時性優勢,使得人與人之間的溝通和交流突破了空間、時間等等限制,讓信息的傳遞變的無處不在。

          但互聯網為我們的生活帶來極大便利的同時,用戶的隱私和通信安全問題也隨之而來。

          對于IM應用開發者來說,信息溝通的開放性也意味著風險性,用戶與網絡和移動設備的高度依賴,也為不法之徒提供了可乘之機。因此,提升即時通訊應用的安全性尤其重要。

          本篇文章將圍繞IM通信連接層的安全問題及實現方案,聚焦IM網絡“鏈路安全”,希望能帶給你啟發。

          學習交流:

          本文已同步發布于:http://www.52im.net/thread-4015-1-1.html

          2、系列文章

          本文是IM通訊安全知識系列文章中的第10篇,此系列總目錄如下:

          3、即時通訊面臨的安全問題

          1)竊取內容:如果在整個即時通訊的通信過程中,其數據內容是未加密或弱加密的,那么其信息被截獲后就可以直接被讀取出來。

          那么,這就會導致用戶數據(包括個人隱私數據)的泄露,甚至可能危害用戶的財產安全(比如微信這類IM中,紅包、錢包都會涉及財產安全)。如果在辦公場景下,被竊取的還可能是公司商業機密,那勢必將會造成更大的經濟損失。

          2)篡改內容:如果通信內容被截獲后,對其進行修改再發送,會破壞信息的正確性和完整性(此消息已非彼消息)。

          3)偽造內容:如果用戶通信憑證(比如token)被竊取或在通信過程中穿插其他信息,就可能為冒用用戶身份騙取與之通信者的信任創造可能,埋下更大的安全隱患。

          4)傳播不法內容:基于即時通訊系統的消息推送能力,不法分子除了可能傳播涉黃、涉賭、暴恐或危害國家安全的信息外,還可能傳播計算機木馬病毒等,可能帶來的危害范圍將進一步擴大。

          4、常用的互聯網攻擊手段

          網絡通信過程中常見的攻擊手段:

          1)移植木馬:過在終端移植木馬,截獲或篡改信息。

          2)偽造應用:通過偽造 APP 或在 APP 中添加后門等方式,使終端用戶誤以為是正常應用進行使用,從而達到其不法目的。

          3)網絡抓包:通過在網絡設備上進行抓包,獲取用戶通信內容。

          4)中間人攻擊:通過劫持 DNS 等手段,使用戶通信連接經過攻擊者的設備,從而達到竊取、篡改等目的。

          5)漏洞挖掘:服務端或終端除了自有的程序以外還包含了各種三方組件或中間件,通過挖掘其上的漏洞,達到不法目的。

          從上圖和手段可知,聊天信息從應用經過網絡到達服務端,這期間的任何一個環節都有可能被人利用。所以,在“危機四伏”的互聯網絡通信中,“安全”必須重視。

          5、密碼學在即時通訊系統中的應用

          5.1 基本常識

          針對前述的安全問題和攻擊手段,將密碼學應用在即時通訊系統連接上,對通信數據進行加密就變得尤為重要。

          密碼學解決信息安全的三要素(CIA)即:

          • 1)機密性(Confidentiality):保證信息不泄露給未經授權的用戶;
          • 2)完整性(Integrity):保證信息從真實的發信者傳送到真實的收信者手中,傳送過程中沒有被非法用戶添加、刪除、替換等;
          • 3)可用性(Availability):保證授權用戶能對數據進行及時可靠的訪問。

          以上表述,好像有點繞口,我們換個通俗一點的表述。。。

          密碼學在網絡通信中的三大作用就是:

          • 1)加密:防止壞人獲取你的數據;
          • 2)認證:防止壞人修改了你的數據而你卻并沒有發現;
          • 3)鑒權:防止壞人假冒你的身份。

          除 CIA 外,還有一些屬性也是要求達到的,如可控性(Controllability)和不可否認性(Non-Repudiation)。

          5.2 在即時通訊中的應用

          作為即時通訊中的關鍵組成,IM即時通訊系統為了實現消息的快速、實時送達,一般需要客戶端與服務器端建立一條socket長連接,用以快速地將消息送達到客戶端。

          通常即時通訊客戶端會以 TCP 或 UDP 的方式與服務器建立連接,同時某些場景下也會使用 HTTP 的方式從服務器獲取或提交一些信息。

          整個過程中所有的數據都需進行加密處理,簡單的數據加密和解密過程可以歸納為:發送方輸入明文 -> 加密 -> 生成密文 -> 傳輸密文 -> 接收方解密 -> 得到明文。

          這其中,會涉及:

          這其中,我國也有一套自有的密碼算法(國密算法):國密算法,即國家商用密碼算法,是由國家密碼管理局認定和公布的密碼算法標準及其應用規范,其中部分密碼算法已經成為國際標準。如 SM 商用系列密碼:對稱加密算法 SM4、非對稱加密算法 SM2、信息摘要算法 SM3。

          6、通信連接層的會話加密

          對于連接層面(鏈路層面)面的加密,應最先考慮的是基于 SSL/TLS 協議進行鏈路加密(比如微信的作法:《微信新一代通信安全解決方案:基于TLS1.3的MMTLS詳解》),這是現代網絡通信安全的基石。

          很多人認為 SSL/TLS 協議是附加在 HTTP 協議上的,是 HTTPS 的一部分(詳見《為什么要用HTTPS?深入淺出,探密短連接的安全性》)。

          其實這種理解不完全正確,SSL/TLS 是獨立于應用層協議的,高層協議可以透明地分布在 SSL/TLS 協議上面。因此基于socket長連接的IM即時消息通訊協議也可以構建在 SSL/TLS 協議上面。

          SSL/TLS 是獨立于應用層協議:

          SSL/TLS 可以被簡單地歸納為:利用基于公私鑰體系的非對稱加密算法,傳輸對稱加解密算法的密鑰,并將后續通訊的數據包基于雙方相同的對稱加解密算法和密鑰進行加密并傳輸,從而達到保證數據安全通訊的目的。

          非對稱加密算法里面的公鑰和私鑰在數學上是相關的,這樣才能用一個加密、用另一個解密。不過,盡管是相關的,但以現有的數學算法,是沒有辦法從一個密鑰算出另一個密鑰。

          另外需要著重強調的是:在系統中不要使用自簽證書,而要使用具備 CA 認證的證書,這樣可以有效的防止中間人攻擊。

          7、基于SSL/TLS的通信連接層如何實現會話的快速恢復

          7.1 概述

          客戶端和服務器端建立 SSL/TLS 握手時,需要完成很多步驟:密鑰協商出會話密鑰、數字簽名身份驗證、消息驗證碼 MAC 等。

          整個握手階段比較耗時的是密鑰協商,需要密集的 CPU 處理。當客戶端和服務器斷開了本次會話連接,那么它們之前連接時協商好的會話密鑰就消失了。在下一次客戶端連接服務器時,便要進行一次新的完整的握手階段。

          這似乎沒什么問題,但是當系統中某一時間段里有大量的連接請求提交時,就會占用大量服務器資源,導致網絡延遲增加。

          為了解決上面的問題,TLS/SSL 協議中提供了會話恢復的方式,允許客戶端和服務器端在某次關閉連接后,下一次客戶端訪問時恢復上一次的會話連接。

          會話恢復有兩種:

          • 1)一種是基于 Session ID 的恢復;
          • 2)一種是使用 Session Ticket TLS 擴展。

          下面來看看兩種方式的優劣。

          7.2 基于Session ID的SSL/TLS長連接會話恢復

          一次完整的握手階段結束后,客戶端和服務器端都保存有這個 Session ID。

          在本次會話關閉,下一次再次連接時:客戶端在 Client Hello 子消息中附帶這個 Session ID 值,服務器端接收到請求后,將 Session ID 與自己在 Server Cache 中保存的 Session ID 進行匹配。

          如果匹配成功:服務器端就會恢復上一次的 TLS 連接,使用之前協商過的密鑰,不重新進行密鑰協商,服務器收到帶 Session ID 的 Client Hello 且匹配成功后,直接發送 ChangeCipherSpec 子協議,告訴 TLS 記錄層將連接狀態切換成可讀和可寫,就完成會話的恢復。

          基于Session ID 會話恢復原理:

          雖然使用 Session ID 進行會話恢復可以減少耗時的步驟,但由于 Session ID 主要保存在服務器 Server Cache 中,若再次連接請求時由于負載均衡設定將請求重定位到了其他服務器上,此時新的服務器 Server Cache 中沒有緩存與客戶端匹配的 Session ID,會導致會話無法恢復無法進行,因此不建議選用  Session ID 方式進行會話恢復。

          7.3 基于SessionTicket的SSL/TLS長連接會話恢復

          一次完整的握手過程后,服務器端將本次的會話數據(會話標識符、證書、密碼套件和主密鑰等)進行加密,加密后生成一個 ticket ,并將 ticket 通過 NewSessionTicket 子消息發送給客戶端,由客戶端來保存,下一次連接時客戶端就將 ticket 一起發送給服務器端,待服務器端解密校驗無誤后,就可以恢復上一次會話。

          基于SessionTicket 會話恢復原理:

          由于加解密都是在服務端閉環進行,多服務只需要共享密鑰就可以完成此過程,相較于 Session ID 的方式,可以不依賴 Server Cache,因此 SessionTicket 會話恢復方式更有利于大型分布式系統使用。

          8、本文小結

          本文分享了IM即時通訊的通信連接層安全知識和加密技術等。

          并著重強調了兩方面內容。首先,在IM即時通訊系統中使用具備 CA 認證的 SSL/TLS 證書可以保證傳輸安全,防止傳輸過程被監聽、防止數據被竊取,確認連接的真實性。其次,利用 SessionTicket 快速地進行會話恢復可以提高整體系統性能,降低連接延時。

          本文的下篇《即時通訊安全篇(十一):IM聊天系統安全手段之傳輸內容端到端加密技術》,將繼續分享基于IM傳輸內容的端到端加密技術,敬請關注。

          9、參考資料

          [1] TCP/IP詳解 - 第11章·UDP:用戶數據報協議

          [2] TCP/IP詳解 - 第17章·TCP:傳輸控制協議

          [3] 網絡編程懶人入門(三):快速理解TCP協議一篇就夠

          [4] 網絡編程懶人入門(四):快速理解TCP和UDP的差異

          [5] 零基礎IM開發入門(二):什么是IM系統的實時性?

          [6] 對稱加密技術在Android平臺上的應用實踐

          [7] 非對稱加密技術的原理與應用實踐

          [8] 常用加解密算法與通訊安全講解

          [9]微信新一代通信安全解決方案:基于TLS1.3的MMTLS詳解

          [10] 為什么要用HTTPS?深入淺出,探密短連接的安全性

          [11] 探討組合加密算法在IM中的應用

          本文已同步發布于:http://www.52im.net/thread-4015-1-1.html

          posted @ 2022-08-22 11:35 Jack Jiang 閱讀(136) | 評論 (0)編輯 收藏

               摘要: 本文引用自InfoQ社區“5億用戶如何高效溝通?釘釘首次對外揭秘即時消息服務DTIM”一文,作者陳萬紅等、策劃褚杏娟,有修訂和改動。一、引言本文是國內企業IM的事實王者釘釘首次對外深度解密其即時消息服務(即DingTalk IM,簡稱DTIM)的技術設計實踐。本篇文章內容將從模型設計原理到具體的技術架構、最底層的存儲模型到跨地域的單元化等,全方位展現了 DTIM 在實際生產...  閱讀全文

          posted @ 2022-08-15 12:32 Jack Jiang 閱讀(249) | 評論 (0)編輯 收藏

               摘要: 本文由vivo互聯網服務器團隊李青鑫分享,有較多修訂和改動。1、引言本文內容來自vivo互聯網服務器團隊李青鑫在“2021 vivo開發者大會”現場的演講內容整理而成(現場演講稿可從本文末附件中下載)。本文將要分享的是手機廠商vivo的系統級推送平臺在架構設計上的技術實踐和總結。這也是目前為止首次由手機廠商分享的自建系統級推送平臺的技術細節,我們也得以借此機會一窺廠商ROO...  閱讀全文

          posted @ 2022-08-09 12:11 Jack Jiang 閱讀(124) | 評論 (0)編輯 收藏

          一、關于RainbowChat-Web

          RainbowChat-Web是一套Web網頁端IM系統,是RainbowChat的姊妹產品(RainbowChat是一套基于開源IM聊天框架 MobileIMSDK(Github地址) 的產品級移動端IM系統)。

          不同于市面上某些開源或淘寶售賣的demo級代碼,RainbowChat-Web的產品級代碼演化自真正運營過的商業產品,其所依賴的通信層核心SDK(即MobileIMSDK-Web)已在數年內經過大量客戶及其輻射的最終用戶的使用和驗證。

          二、v4.1 版更新內容

          此版更新內容更多歷史更新日志):

          • 1)[bug][前端]解決了掉線后發出的消息,在被判定未送達的情況下,重連成功時會再次重發的問題(這是MobileIMSDK-Web的bug);
          • 2)[優化][前端]解決了發送的html等內容,對方顯示正常,而自已這邊顯示不正常的問題(沒被轉義);
          • 3)[優化][服務端-獨立交付版]解決了log4j2的兩個jar包沖突導致在linux下不能正常輸出log的問題;
          • 4)[優化][服務端-RainbowChatMQserver]優化了使用mysql8.0驅動時,不能正確讀取SQL異常信息的問題(會報空指針異常);
          • 5)[優化][前端]解決了位置消息發送功能無法正常使用的問題(高德地圖官方API升級,已適配并升級完成);
          • 6)[優化][前端]解決了位置消息查看時的地圖控制工具不正常的問題(高德地圖官方API升級,已適配并升級完成)。

          升級后的位置消息相關功能截圖(更多截圖點此查看):

          三、關于兼容性

          截止目前:RainbowChat-Web努力保證在各主流系統、主流瀏覽器、不同分辨率屏幕上的一致體驗,包括但不限于:Chrome、Safari、FireFox、Edge、360瀏覽器、世界之窗瀏覽器等▼

          ▲ 在各種主流瀏覽器上的運行情況更多截圖點此進入、更多演示視頻點此進入

          ▲ 超寬屏上的顯示情況更多截圖點此進入更多演示視頻點此進入

           

          ▲ 不同系統、不同分辨率屏幕的真機運行情況更多截圖點此進入、更多演示視頻點此進入) 

          四、主要界面截圖概覽

           

          ▲ 主界面更多截圖點此進入、更多演示視頻點此進入

          ▲ 主界面(聊天窗全屏時)更多截圖點此進入、更多演示視頻點此進入

          ▲ 主界面(聊天窗關閉時)更多截圖點此進入、更多演示視頻點此進入

          posted @ 2022-08-06 12:14 Jack Jiang 閱讀(126) | 評論 (0)編輯 收藏

               摘要: 本文由vivo互聯網技術團隊LinDu、Li Guolin分享,有較多修訂和改動。1、引言IM即時消息模塊是直播系統的重要組成部分,一個穩定、有容錯、靈活的、支持高并發的消息模塊是影響直播系統用戶體驗的重要因素。本文針對秀場直播,結合我們一年以來通過處理不同的業務線上問題,進行了技術演進式的IM消息模塊架構的升級與調整,并據此進行了技術總結、整理成文,希望借此機會分享給大家。在目前大部分主流的直播...  閱讀全文

          posted @ 2022-08-01 12:37 Jack Jiang 閱讀(138) | 評論 (0)編輯 收藏

          本文由作者“大白菜”分享,有較多修訂和改動。注意:本系列是給IM初學者的文章,IM老油條們還望海涵,勿噴!

          1、引言

          前兩篇《編碼實踐篇(單聊功能)》、《編碼實踐篇(群聊功能)》分別實現了控制臺版本的IM單聊和群聊的功能。

          通過前兩篇這兩個小案例來體驗的只是Netty在IM系統這種真實的開發實踐,但對比在真實的Netty應用開發當中,本系列的案例是非常的簡單的,主要目的其實是讓大家可以更好地了解其原理,從而寫出更高質量的 Netty 代碼。

          不過,雖然 Netty 的性能很高,但是也不能保證隨意寫出來的項目就是性能很高的,所以本篇將主要講解幾個基于Netty的IM系統的優化實戰技術點。

          學習交流:

          本文同步發布于:http://www.52im.net/thread-3988-1-1.html

          2、寫在前面

          建議你在閱讀本文之前,務必先讀本系列的前三篇《IM系統設計篇》、《編碼實踐篇(單聊功能)》、《編碼實踐篇(群聊功能)》。

          最后,在開始本文之前,請您務必提前了解Netty的相關基礎知識,可從本系列首篇《IM系統設計篇》中的“知識準備”一章開始。

          3、系列文章

          本文是系列文章的第3篇,以下是系列目錄:

          4、基于Netty的IM系統常見優化方向

          常見優化方向腦圖:

          我們逐條詳細解釋一下這些優化的目的:

          • 1)心跳檢測:主要是避免連接假死現象;
          • 2)連接斷開:則刪除通道綁定屬性、刪除對應的映射關系,這些信息都是保存在內存當中的,如果不刪除則造成資源浪費;
          • 3)性能問題:用戶 ID 和 Channel 的關系綁定存在內存當中,比如:Map,key 是用戶 ID,value 是 Channel,如果用戶量多的情況(客戶端數量過多),那么服務端的內存將被消耗殆盡;
          • 4)性能問題:每次服務端往客戶端推送消息,都需從Map里查找到對應的Channel,如果數量較大和查詢頻繁的情況下如何保證查詢性能;
          • 5)安全問題:HashMap 是線程不安全的,并發情況下,我們如何去保證線程安全;
          • 6)身份校驗:如何 LoginHandler 是負責登錄認證的業務 Handler,AuthHandler 是負責每次請求時校驗該請求是否已經認證了,這些 Handler 在鏈接就緒時已經被添加到 Pipeline 管道當中,其實,我們可以采用熱插拔的方式去把一些在做業務操作時用不到的 Handler 給剔除掉。

          以上是基于Netty的IM系統開發當中,需要去注意的技術優化點,當然還有很多其他的細節,比如:線程池這塊,需要大家慢慢去從實戰中積累。

          5、本篇優化方向

          本篇主要的優化內容主要是在第二篇單聊功能第三篇群聊功能的基礎上繼續完善幾點。

          具體的優化方向如下:

          • 1)無論客戶端還是服務端都分別只有一個 Handler,這樣的話,業務越來越多,Handler 里面的代碼就會越來越臃腫,我們應該想辦法把 Handler 拆分成各個獨立的 Handler;
          • 2)如果拆分的 Handler 很多,每次有連接進來,那么都會觸發 initChannel () 方法,所有的 Handler 都得被 new 一遍,我們應該把這些 Handler 改成單例模式(不需要每次都 new,提高效率);
          • 3)發送消息時,無論是單聊還是群聊,對方不在線,則把消息緩存起來,等待其上線再推送給他;
          • 4)連接斷開時,無論是主動和被動,需要刪除 Channel 屬性、刪除用戶和 Channel 映射關系。

          6、業務拆分以及單例模式優化

          6.1 概述

          主要優化細節如下:

          • 1)自定義 Handler 繼承 SimpleChannelInboundHandler,那么解碼的時候,會自動根據數據格式類型轉到相應的 Handler 去處理;
          • 2)@Shareable 修飾 Handler,保證 Handler 是可共享的,避免每次都創建一個實例。

          6.2 登錄Handler優化

          @ChannelHandler.Sharable

          public class ClientLogin2Handler extends SimpleChannelInboundHandler<LoginResBean> {

              //1.構造函數私有化,避免創建實體

              private ClientLogin2Handler(){}

              //2.定義一個靜態全局變量

              public static ClientLogin2Handler instance=null;

              //3.獲取實體方法

              public static ClientLogin2Handler getInstance(){

                  if(instance==null){

                      synchronized(ClientLogin2Handler.class){

                          if(instance==null){

                              instance=new ClientLogin2Handler();

                          }

                      }

                  }

                  return instance;

              }

           

              protected void channelRead0(

                  ChannelHandlerContext channelHandlerContext,

                  LoginResBean loginResBean) throws Exception {

           

                  //具體業務代碼,參考之前

              }

          }

          6.3 消息發送Handler優化

          @ChannelHandler.Sharable

          public class ClientMsgHandler extends SimpleChannelInboundHandler<MsgResBean> {

              //1.構造函數私有化,避免創建實體

              private ClientMsgHandler(){}

              //2.定義一個靜態全局變量

              public static ClientMsgHandler instance=null;

              //3.獲取實體方法

              public static ClientMsgHandler getInstance(){

                  if(instance==null){

                      synchronized(ClientMsgHandler.class){

                          if(instance==null){

                              instance=new ClientMsgHandler();

                          }

                      }

                  }

                  return instance;

              }

           

              protected void channelRead0(

                  ChannelHandlerContext channelHandlerContext,

                  MsgResBean msgResBean) throws Exception {

           

                  //具體業務代碼,參考之前

              }

          }

          6.4 initChannel方法優化

          .handler(newChannelInitializer<SocketChannel>() {

              @Override

              public void initChannel(SocketChannel ch) {

                  //1.拆包器

                  ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,5,4));

                  //2.解碼器

                  ch.pipeline().addLast(new MyDecoder());

                  //3.登錄Handler,使用單例獲取

                  ch.pipeline().addLast(ClientLogin2Handler.getInstance());

                  //4.消息發送Handler,使用單例獲取

                  ch.pipeline().addLast(ClientMsgHandler.getInstance());

                  //5.編碼器

                  ch.pipeline().addLast(new MyEncoder());

              }

          });

          6.5 小結

          這種業務拆分以及單例模式優優化是Netty開發當中很常用的,可以更好的維護基于Netty的代碼并提高應用性能。

          7、數據緩存優化

          為了提高用戶體驗,在發送消息(推送消息)時,如果接收方不在線,則應該把消息緩存起來,等對方上線時,再推送給他。

          7.1 數據緩存到集合

          //1.定義一個集合存放數據(真實項目可以存放數據庫或者redis緩存),這樣數據比較安全。

          private List<Map<Integer,String>> datas=new ArrayList<Map<Integer,String>>();

           

          //2.服務端推送消息

          private void pushMsg(MsgReqBean bean,Channel channel){

              Integer touserid=bean.getTouserid();

              Channel c=map.get(touserid);

           

              if(c==null){//對方不在線

                  //2.1存放到list集合

                  Map<Integer,String> data=new HashMap<Integer, String>();

                  data.put(touserid,bean.getMsg());

                  datas.add(data);

           

                  //2.2.給消息“發送人”響應

                  MsgResBean res=new MsgResBean();

                  res.setStatus(1);

                  res.setMsg(touserid+">>>不在線");

                  channel.writeAndFlush(res);

           

              }else{//對方在線

                  //2.3.給消息“發送人”響應

                  MsgResBean res=new MsgResBean();

                  res.setStatus(0);

                  res.setMsg("發送成功);

                  channel.writeAndFlush(res);

           

                  //2.4.給接收人推送消息

                  MsgRecBean res=new MsgRecBean();

                  res.setFromuserid(bean.getFromuserid());

                  res.setMsg(bean.getMsg());

                  c.writeAndFlush(res);

              }

          }

          7.2 上線推送

          private void login(LoginReqBean bean, Channel channel){

              Channel c=map.get(bean.getUserid());

              LoginResBean res=new LoginResBean();

              if(c==null){

                  //1.添加到map

                  map.put(bean.getUserid(),channel);

                  //2.給通道賦值

                  channel.attr(AttributeKey.valueOf("userid")).set(bean.getUserid());

                  //3.登錄響應

                  res.setStatus(0);

                  res.setMsg("登錄成功");

                  res.setUserid(bean.getUserid());

                  channel.writeAndFlush(res);

           

                  //4.根據user查找是否有尚未推送消息

                  //思路:根據userid去lists查找.......

           

              }else{

                  res.setStatus(1);

                  res.setMsg("該賬戶目前在線");

                  channel.writeAndFlush(res);

              }

          }

          8、連接斷開事件處理優化

          如果客戶端網絡故障導致連接斷開了(非主動下線),那么服務端就應該能監聽到連接的斷開,且此時應刪除對應的 map 映射關系。但是映射關系如果沒有刪除掉,將導致服務器資源沒有得到釋放,進而影響客戶端的下次同一個賬號登錄以及大量的客戶端掉線時性能。

          8.1 正確寫法

          實例:

          public class ServerChatGroupHandler extends ChannelInboundHandlerAdapter {

              //映射關系

              private static Map<Integer, Channel> map=new HashMap<Integer, Channel>();

              //連接斷開,觸發該事件

              @Override

              public void channelInactive(ChannelHandlerContext ctx) throws Exception {

                  //1.獲取Channel

                  Channel channel=ctx.channel();

           

                  //2.從map里面,根據Channel找到對應的userid

                  Integer userid=null;

                  for(Map.Entry<Integer, Channel> entry : map.entrySet()){

                      Integer uid=entry.getKey();

                      Channel c=entry.getValue();

                      if(c==channel){

                          userid=uid;

                      }

                  }

                  //3.如果userid不為空,則需要做以下處理

                  if(userid!=null){

                      //3.1.刪除映射

                      map.remove(userid);

                      //3.2.移除標識

                      ctx.channel().attr(AttributeKey.valueOf("userid")).remove();

                  }

              }

          }

          8.2 錯誤寫法

          Channel 斷開,服務端監聽到連接斷開事件,但是此時 Channel 所綁定的屬性已經被移除掉了,因此這里無法直接獲取的到 userid。

          實例:

          public class ServerChatGroupHandler extends ChannelInboundHandlerAdapter {

              //映射關系

              private static Map<Integer, Channel> map=new HashMap<Integer, Channel>();

           

              //連接斷開,觸發該事件

              @Override

              public void channelInactive(ChannelHandlerContext ctx) throws Exception {

                  //1.獲取Channel綁定的userid

                  Object userid=channel.attr(AttributeKey.valueOf("userid")).get();

           

                  //2.如果userid不為空

                  if(userid!=null){

                      //1.刪除映射

                      map.remove(userid);

                      //2.移除標識

                      ctx.channel().attr(AttributeKey.valueOf("userid")).remove();

                  }

              }

          }

          9、本篇小結

          本篇內容還是相對容易理解的,主要是優化前面兩篇實現的IM聊天功能,優化內容是業務 Handler 的拆分以及使用單例模式、接受人不在線則緩存數據、等其上線再推送、監聽連接斷開刪除對應的映射關系。

          限于篇幅,本系列文章文章沒辦法真正講解開發一個完整IM系統所涉及的方方面面,如果有興趣,可以繼續閱讀更有針對性的IM開發文章,比如IM架構設計IM通信協議、IM通信安全群聊優化、弱網優化、網絡保活等。

          10、參考資料

          [1] 新手入門:目前為止最透徹的的Netty高性能原理和框架架構解析

          [2] 理論聯系實際:一套典型的IM通信協議設計詳解

          [3] 淺談IM系統的架構設計

          [4] 簡述移動端IM開發的那些坑:架構設計、通信協議和客戶端

          [5] 一套海量在線用戶的移動端IM架構設計實踐分享(含詳細圖文)

          [6] 一套原創分布式即時通訊(IM)系統理論架構方案

          [7]  一套高可用、易伸縮、高并發的IM群聊、單聊架構方案設計實踐

          [8] 一套億級用戶的IM架構技術干貨(上篇):整體架構、服務拆分等

          [9] 從新手到專家:如何設計一套億級消息量的分布式IM系統

          [10] 基于實踐:一套百萬消息量小規模IM系統技術要點總結

          [11] 探探的IM長連接技術實踐:技術選型、架構設計、性能優化

          [12] 拿起鍵盤就是干,教你徒手開發一套分布式IM系統

          [13] 萬字長文,手把手教你用Netty打造IM聊天

          [14] 基于Netty實現一套分布式IM系統

          [15] SpringBoot集成開源IM框架MobileIMSDK,實現即時通訊IM聊天功能

          本文同步發布于:http://www.52im.net/thread-3988-1-1.html

          posted @ 2022-07-25 12:02 Jack Jiang 閱讀(137) | 評論 (0)編輯 收藏

          一、更新內容簡介

          本次更新為次要版本更新,進行了若干優化(更新歷史詳見:碼云 Release Nodes)??赡苁鞘忻嫔衔ㄒ煌瑫r支持 UDP+TCP+WebSocket 三種協議的同類開源IM框架。

          二、MobileIMSDK簡介

          MobileIMSDK 是一套專為移動端開發的原創IM通信層框架:

          • 歷經8年、久經考驗;
          • 超輕量級、高度提煉,lib包50KB以內;
          • 精心封裝,一套API同時支持UDP、TCP、WebSocket三種協議(可能是全網唯一開源的);
          • 客戶端支持 iOSAndroid標準JavaH5、小程序(開發中..)、Uniapp(開發中..);
          • 服務端基于Netty,性能卓越、易于擴展;??
          • 可與姊妹工程 MobileIMSDK-Web 無縫互通實現網頁端聊天或推送等;??
          • 可應用于跨設備、跨網絡的聊天APP、企業OA、消息推送等各種場景。

          MobileIMSDK工程始于2013年10月,起初用作某產品的即時通訊底層實現,完全從零開發,技術自主可控!

          您可能需要:查看關于MobileIMSDK的詳細介紹

          三、代碼托管同步更新

          OsChina.net

          GitHub.com

          四、MobileIMSDK設計目標

          讓開發者專注于應用邏輯的開發,底層復雜的即時通訊算法交由SDK開發人員,從而解偶即時通訊應用開發的復雜性。

          五、MobileIMSDK框架組成

          整套MobileIMSDK框架由以下5部分組成:

          1. Android客戶端SDK:用于Android版即時通訊客戶端,支持Android 2.3及以上,查看API文檔;
          2. iOS客戶端SDK:用于開發iOS版即時通訊客戶端,支持iOS 8.0及以上,查看API文檔;
          3. Java客戶端SDK:用于開發跨平臺的PC端即時通訊客戶端,支持Java 1.6及以上,查看API文檔;
          4. H5客戶端SDK:暫無開源版,查看精編注釋版;
          5. 服務端SDK:用于開發即時通訊服務端,支持Java 1.7及以上版本,查看API文檔。

          整套MobileIMSDK框架的架構組成:

           另外:MobileIMSDK可與姊妹工程 MobileIMSDK-Web 無縫互通,從而實現Web網頁端聊天或推送等。

          六、MobileIMSDK v6.2更新內容 

          【重要說明】:

          MobileIMSDK v6.2 為次要版本,進行了若干優化! 查看詳情

          【新增的特性】:

          1. [服務端] 新增兩個聊天消息前置處理回調,方便開發者進行內容鑒黃、過濾、修改等運營管理;
          2. [服務端] 新增新增了一個與 Web 互通情況下的 C2C 模式回調,用于開發者在互通模式下實現離線消息 Push 邏輯;

          【其它優化和提升】:

          1. [Andriod] 支持最新的 Andriod 12,解決了 Demo 工程中的 Andriod12 兼容問題;
          2. [Andriod] 解決了 Demo 工程在最新 Android Studio 編譯時報方法數超過 65535 的經典問題;
          3. [服務端] 升級 log4j2 至 2.17.0,解決 Log4j2 遠程代碼執行高危漏洞;
          4. [服務端] 為 ServerEventListener 類中的 onUserLogout 回調增加 beKickoutCode 參數;
          5. [服務端] [優化] 嘗試解決與 Web 互通情況下,MQProvider 中的 work 方法會因異步消息導致的 AlreadCloseException 問題;

          【版本地址】:

          https://gitee.com/jackjiang/MobileIMSDK/releases/6.2

          posted @ 2022-07-20 10:29 Jack Jiang 閱讀(103) | 評論 (0)編輯 收藏

               摘要: 本文由作者“大白菜”分享,有較多修訂和改動。注意:本系列是給IM初學者的文章,IM老油條們還望海涵,勿噴!1、引言接上兩篇《IM系統設計篇》、《編碼實踐篇(單聊功能)》,本篇主要講解的是通過實戰編碼實現IM的群聊功能,內容涉及群聊技術實現原理、編碼實踐等知識。學習交流:- 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM》- 開源IM框架源碼:https://...  閱讀全文

          posted @ 2022-07-18 15:06 Jack Jiang 閱讀(114) | 評論 (0)編輯 收藏

          僅列出標題
          共50頁: First 上一頁 17 18 19 20 21 22 23 24 25 下一頁 Last 
          Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 兴安县| 墨竹工卡县| 酉阳| 灵山县| 灌阳县| 定兴县| 桐柏县| 新巴尔虎左旗| 龙游县| 亚东县| 诸暨市| 陕西省| 永靖县| 碌曲县| 阳泉市| 寻乌县| 青浦区| 长汀县| 大田县| 宜黄县| 睢宁县| 尚志市| 军事| 个旧市| 沙坪坝区| 施秉县| 昌图县| 辛集市| 梅州市| 宿松县| 疏附县| 新兴县| 哈尔滨市| 砚山县| 芦溪县| 英德市| 阿克陶县| 彭泽县| 禄丰县| 峨山| 崇文区|