Jack Jiang

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

为了更好地分类阅读52im.net 总计1000多篇精编文章,我将在每周三推送新的一期技术文集,本次是第3 期。

第 

[标题] 高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少

[链接] http://www.52im.net/thread-561-1-1.html

[摘要] 到底一台服务器能够支持多少TCP并发连接呢?这就是本文要讨论的问题。


第 

[标题] 高性能网络编程(二):上一个10年,著名的C10K并发连接问题

[链接] http://www.52im.net/thread-566-1-1.html

[摘要] 了解C10K问题及其解决思路,通过举一反三,或许可以为你以后面对类似问题提供更多可借鉴的思想和解决问题的实践思路。


第 

[标题] 高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了

[链接] http://www.52im.net/thread-568-1-1.html

[摘要] 本文将讨论单机服务器实现C10M(即单机千万并发连接)的可能性及其思路。


第 

[标题] 高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索

[链接] http://www.52im.net/thread-578-1-1.html

[摘要] 本文内容由京东的资深架构师闫国旗分享,以分享者多年的实践和总结,进一步探讨解决C10M问题的理论可行性。


第 

[标题] 高性能网络编程(五):一文读懂高性能网络编程中的I/O模型

[链接] http://www.52im.net/thread-1935-1-1.html

[摘要] 本文旨在为大家提供有用的高性能网络编程的I/O模型概览以及网络服务进程模型的比较,以揭开设计和实现高性能网络架构的神秘面纱。


第 

[标题] 高性能网络编程(六):一文读懂高性能网络编程中的线程模型

[链接] http://www.52im.net/thread-1939-1-1.html

[摘要] 限于篇幅原因,请将本文与《高性能网络编程(五):一文读懂高性能网络编程中的I/O模型》连起来读,这样会让知识更连贯。


第 

[标题] 高性能网络编程(七):到底什么是高并发?一文即懂!

[链接]http://www.52im.net/thread-3120-1-1.html

[摘要] 在面视即时通讯相关工作的时候,高并发也是必谈问题,那到底什么是高并发?嗯,真要说出个所以然来,还真有点懵...本文就与大家一起探讨学习一下。


第 

[标题] 从根上理解高性能、高并发(一):深入计算机底层,理解线程与线程池

[链接] http://www.52im.net/thread-3272-1-1.html

[摘要] 返璞归真、回归本质,这些技术特征背后的底层原理到底是什么?如何能通俗易懂、毫不费力真正透彻理解这些技术背后的原理,正是《从根上理解高性能、高并发》系列文章所要分享的。


第 

[标题] 从根上理解高性能、高并发(二):深入操作系统,理解I/O与零拷贝技术

[链接] http://www.52im.net/thread-3280-1-1.html

[摘要] 对于即时通讯IM这种系统的开发来说,网络通信知识确实非常重要,但回归到技术本质,实现网络通信本身的这些技术特征:包括上篇提到的线程池、零拷贝、多路复用、事件驱动等等,它们的本质是什么?底层原理又是怎样?这就是整理本系列文章的目的,希望对你有用。


第 10 

[标题] 从根上理解高性能、高并发(三):深入操作系统,彻底理解I/O多路复用

[链接] http://www.52im.net/thread-3287-1-1.html

[摘要] 本篇将以更具象的文件这个话题入手,带你一步步理解高性能、高并发服务端编程时无法回避的I/O多路复用及相关技术。


第 11 

[标题] 从根上理解高性能、高并发(四):深入操作系统,彻底理解同步与异步

[链接] http://www.52im.net/thread-3296-1-1.html

[摘要] 本篇将从基础着眼,为你讲解什么是同步和异步,以及这两个极为重要的概念在高并发、高性能技术中编程中到底意味着什么。


第 12 

[标题] 从根上理解高性能、高并发(五):深入操作系统,理解高并发中的协程

[链接] http://www.52im.net/thread-3306-1-1.html

[摘要] 了解和掌握协程技术对于很多程序员(尤其海量网络通信应用的后端程序员)来说是相当有必要的,本文正是为你解惑协程技术原理而写。


第 13 

[标题] 从根上理解高性能、高并发(六):通俗易懂,高性能服务器到底是如何实现的

[链接] http://www.52im.net/thread-3315-1-1.html

[摘要] 本篇是本系列文章的完结篇,你将能了解到,一个典型的服务器端是如何利用前5篇中讲解的各单项技术从而实现高性能高并发的。


第 14 

[标题] 从根上理解高性能、高并发(七):深入操作系统,一文读懂进程、线程、协程

[链接]http://www.52im.net/thread-3357-1-1.html

[摘要] 本篇是本系列文章的临时续篇,本篇将由浅入深,总结进程、线程、协程这3个技术概念,将3者的技术原理、用途、关系进行了系统梳理和总结,希望有助于解决你这方面的技术困惑。

我是Jack Jiang,我为自已带盐!

https://github.com/JackJiang2011/MobileIMSDK/

posted @ 2022-10-24 12:04 Jack Jiang 阅读(102) | 评论 (0)编辑 收藏

本文由融云技术团队分享,有修订和改动。

1、引言

Electron 凭借其相对更低的研发成本投入、强大的跨平台支持、拥有基数庞大的 Javascript 开发者受众等优势,在 PC 端跨平台桌面开发领域异军突起,大受欢迎。

本文分享的是融云基于Electron的IM跨平台PC端SDK改造过程中所总结的一些实践经验,希望对你有用。

* 友情提示:如果您对Electron的基础概念还不太了解,建议您先从本系列文章的首篇《快速了解新一代跨平台桌面技术——Electron》和第2篇《Electron初体验(快速开始、跨进程通信、打包、踩坑等)》开始阅读,否则可能难以理解本文的有关内容。

学习交流:

(本文已同步发布于:http://www.52im.net/thread-4060-1-1.html

2、系列文章

本文是系列文章中的第5篇,本系列总目录如下:

3、本次改造的技术目标

针对本次改造,我们需要达到以下4个技术目标:

  • 1)需提供与传统桌面通讯软件相匹配的能力支持;
  • 2)需实现浏览器与Electron不同运行时代码的高度复用;
  • 3)便于开发者构建多窗口、多进程的复杂桌面端应用;
  • 4)需同步适配同一IM端SDK的多个版本。

以下,我们将逐条讨论这4个目标所有实现的具体技术内容。

4、技术目标1:需提供与传统桌面通讯软件相匹配的能力支持

相较于 B/S 架构的 Web 网页应用,我们期望能够在 Electron 环境下向开发者提供更为丰富的本地化能力,以及比 Websocket(或Comet)更高效的Socket实时双工通信通道。

借助这些原本在浏览器环境下不便实现的技术能力,来整体提高用户对于桌面端产品的使用体验,将 Electron 作为一个 C/S 架构软件运行平台的潜力发挥到最大。(白话就是,我们希望借助Electron这个框架,将原本Web端的一些鸡肋能力,做到像原生富客户端一样)

5、技术目标2:浏览器与Electron不同运行时代码的高度复用

由于 Electron 与标准 Web 应用拥有几乎相同的技术生态,因此多数产品会要求前端代码工程兼顾浏览器与 Electron。

也就是说,一套代码既要打包为传统桌面端应用(利用Electron),又可发布为浏览器中运行的 Web 网页应用。

基于此,我们提供的 IM SDK 需要在两种不同的运行时环境下做到差异最小化,避免开发者编写冗余的平台兼容代码。(白话就是,尽可能在基于Electron的桌面端和纯Web网页端之间重用更多的代码,不然又得多撸一个全新的Electron端,这得多费劲)

6、技术目标3:便于开发者构建多窗口、多进程的复杂桌面端应用

Electron 通过对 IPC 能力的封装为桌面端应用开发提供了较完善的跨进程通讯方案,借助此能力,开发者构建的桌面端应用也逐渐趋于复杂。

比较典型的如桌面端IM产品:通常用一个独立窗口做基础的 IM 聊天业务,一个窗口做历史聊天记录查询业务。

当有音视频会议业务场景时,还需要再开一个窗口做会议业务。

甚至有开发者提出了与每个聊天对象都保持一个独立聊天窗口的需求(产品形态如 QQ)。

在这类需求下,长连接状态维持、消息同步变得异常复杂,原因在于以下3个方面。

  • 1)若每个进程窗口都维持独立长连接,难免会出现某一进程连接与其他进程连接状态不同步。且开发者需在各进程同时维护连接状态,复杂度较高。同时还会造成服务的并发能力下降。
  • 2)若仅有单一主窗口进行连接维持,其他窗口通过 IPC 能力将主窗口作为连接代理,则需要在主进程、各渲染进程中维护复杂的跨进程通讯业务代码,从而推高项目整体的复杂度。
  • 3)目前的 Electron 开发者绝大多数来自于 Web 开发者,既有编程思维是建立在浏览器页面内单进程单线程的应用模型下构建起来的,对于处理此类多进程模型的产品开发缺乏相关的经验积累。

为降低类似需求场景的业务实现复杂度,我们需要在 PaaS 能力层面上解决多进程连接共享、多进程消息同步问题,让开发者在既有编程思维模式下将每个业务实现的更为顺畅。

7、技术目标4:需同步适配同一IM端SDK的多个版本

我们的既有Web端 IM SDK 存在一个端多个不同版本的情况(主要是为了兼容老用户,旧版本很难一刀切直接扔掉,只能新老版末同时并存)。

各版本都有不同数量的客户积累,且各版本 API 接口设计迥异,跨版本升级成本较高。

考虑到使用不同版本的客户未来将业务向 Electron 迁移的可能性,我们期望通过架构设计的改进来避免既有客户做过多的集成代码修改,在确保既有客户不因版本升级而流失的前提下降低 Web 研发团队自身的多版本 SDK 维护成本。

8、本次改造的落地实践

针对上面章节中确定的技术目标,我们将从以下3个方向着手落地实践:

  • 1)剥离各版本的共同业务与对外差异性 API 定义;
  • 2)Electron 与浏览器平台下 IM SDK 的区分;
  • 3)解决多进程消息同步、多进程连接共享问题。
    以下,我们将逐条分享这3个方面的具体实践内容。

9、落地实践1:剥离各版本的共同业务与对外差异性API定义

我们的 IM SDK 各版本分别为不同的代码仓库独立维护,互无干系。(白话就是,所有端的IM SDK都是独立开发,从头造轮子)

这导致所有的功能(包括即将开发的 Electron 桌面解决方案)都可能要在各个版本仓库上单独实现,不仅开发成本高,还会导致实现质量无法保证、或代码实现不统一,同时也推高了产研后续流程的测试、上线等环节的成本。

▲ IM SDK 不同版本独立维护

基于前述技术目标4的要求,在既有现状下继续开发,就意味着需要在两个版本的基础上做不同实现,既不符合程序员的代码审美,也影响团队整体的研发效率。(白话就是,如果又要从头造轮子实在太难受)

为更好地达成技术目标4,团队决定优先通过重构将既有业务分层,即各个版本所必须的业务代码抽象下沉为 IM Engine 包,并为各个版本 IM SDK 分别实现不同的API Layer以便与既有线上版本接口对齐,这样既可以降低团队的研发成本,也可以满足既有线上客户后续的升级需求。

▲ 重构代码实现业务分层

完成业务分层后,对于 IM SDK 有依赖的其他产品如 RTC SDK,也都可以摆脱对 IM SDK 接口的依赖而直接调用 Engine 层接口,业务层在拓展 RTC 业务时,也就无需再考虑 IM SDK 的版本问题。

▲ 业务分层后的结构将保证拓展性

做分层的另一个考虑还为了达成技术目标2,将与业务层的交互限制在 API 层,在 Engine 中处理 Electron 与浏览器两种运行时下的代码差异,业务层只需关心 IM SDK 的接口调用而无需关心底层差异,确保业务层在两种运行时下只需要维护极少甚至无需维护兼容代码,便于业务层更专注于业务开发。

10、落地实践2:Electron 与浏览器平台下 IM SDK 的区分

在将 Engine 与业务层隔离后(见上一节),需要考虑 Engine 在不同的运行时下的关键能力差异,并依据能力差异落实 Engine 的底层设计。

Electron 环境下的连接、消息存储等能力由 c++ 模块编写提供(即后面提到的 CppProto.node):

在浏览器与 Electron 平台下,从连接管理、到消息收发等实现方式迥异,团队需要对 Engine 包继续分层,通过 AEngine 抽象类来定义 IM Engine 的能力接口,并抽象 APIContext 类用来管理 AEngine 的能力调用。

考虑到纯 Web 应用构建尺寸问题,Electron 的能力实现代码不应被打包到标准 Web 页面内,因此还需要将 Electron 平台下的实现代码单独抽离出来作为一个独立包(即ElectronSolution),作为可选模块由开发者选择安装使用。

▲ Electron相关的代码抽离为可选模块

如上图所示,CppEngine 在 ElectronSolution 包中定义,其需要由开发者在 Electron 应用创建 BrowserWindow 实例时通过 webPreferences.preload 配置属性向渲染进程窗口预挂载。

APIContext 在初始化 AEngine 实例时,优先检测 CppEngine 是否已定义。当发现有 CppEngine 定义时,则初始化 CppEngine 提供更丰富的本地化能力,否则初始化 JSEngine。

就像下面的代码的展现的逻辑:

const engine: AEngine = typeofCppEngine !== 'undefined'

  ? newCppEngine()

  : newJSEngine()

11、落地实践3:解决多进程消息同步、多进程连接共享问题

ElectronSolution 包截止目前的设计中,所有代码都运行在渲染进程内。

这意味着每个进程彼此独立,都在维护独立的进程状态,无法满足目标 3 中多进程状态同步、连接共享的需求。

为了解决该问题,需要将 CppProto.node 模块放到主进程,在主进程中实现连接管理、消息收发等能力,多个渲染进程通过 IPC 通信共享主进程状态。

▲ 多个渲染进程通过 IPC 通信共享主进程状态

为了达成技术目标3的要求,ElectronSolution 需要拆分为两个子包,即Main 与 Renderer。

具体就是:

  • 1)Main 包运行在主进程内,负责维持 CppProto.node 模块的调用,实现底层连接管理、消息管理等功能,同时通过 Electron 提供的 ipcMain 与各渲染进程维持通信;
  • 2)Renderer 包中定义 CppEngine 类,继承自 Engine 包内的 AEngine 抽象类,依然通过 webPreferences.preload 用来作为主进程的代理,通过 ipcRenderer 与主进程维持通信。

▲ 拆分为Main与Renderer两个子包

修改完成后,ElectronSolution 包的整体结构基本确定。

以下列出 ElectronSolution 包关键目录结构供参考:

node_modules/@rongcloud/electron-solution

├── index.js

├── main

│   ├── addon

│   │   ├── binding

│   │   │   └── electron-v{electron-version}-{platform}-{arch}.node

│   │   └── index.js

│   ├── dist

│   │   └── index.js

│   ├── index.js

│   └── package.json

└── renderer

│   ├── dist

│   │   └── index.js

│   ├── index.js

│   └── package.json

└── package.json

基于上述架构变动,当业务层需要在多个渲染进程中实现 IM 能力时,仅需要关注在各个进程中的 IM SDK 接口调用,由 ElectronSolution 处理多进程之间的状态同步问题。

当开发者期望由既有 Web 业务向 Electron 平台迁移时,开发者也无需修改既有的 Web 业务代码,仅需要增量编写主进程代码相关功能实现,将 ElectronSolution 安装并集成到 Electron 桌面端应用中即可。

最终,我们形成了以下这样的IM SDK整体结构:

12、未来的规划

除了上述IM相关业务,后续我们还打算在Electron平台下提升RTC的场景能力。

目前,Electron 平台下由 Chromium 原始提供的 WebRTC 能力对于开发桌面级音视频应用软件来说相对薄弱,我们有计划探索借助 node.js 的拓展能力,提供更为底层的 WebRTC 能力拓展如音效、音质、视频特效等。

13、参考资料

[1] 快速了解新一代跨平台桌面技术——Electron

[2] Electron初体验(快速开始、跨进程通信、打包、踩坑等)

[3] WebSocket从入门到精通,半小时就够!

[4] Comet技术详解:基于HTTP长连接的Web端实时通信技术

[5] 一套海量在线用户的移动端IM架构设计实践分享(含详细图文)

[6] Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE

[7] 搞懂现代Web端即时通讯技术一文就够:WebSocket、socket.io、SSE

(本文已同步发布于:http://www.52im.net/thread-4060-1-1.html

posted @ 2022-10-20 11:53 Jack Jiang 阅读(78) | 评论 (0)编辑 收藏

为了更好地分类阅读52im.net 总计1000多篇精编文章,我将在每周三推送新的一期技术周刊,本次是第期。

第 

[标题] 脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

[链接] http://www.52im.net/thread-1729-1-1.html

[摘要]网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一。本篇文章尝试使用动画图片的方式,来对这个知识点进行“脑残式”讲解(哈哈),期望读者们可以更加简单、直观地理解TCP网络通信交互的本质。


第 

[标题] 脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?

[链接] http://www.52im.net/thread-1732-1-1.html

[摘要] 套接字socket是大多数程序员都非常熟悉的概念,它是计算机网络编程的基础,TCP/UDP收发消息都靠它。本篇文章依然尝试使用动画图片的方式,来对这个知识点进行“脑残式”讲解(哈哈),期望读者们可以更加简单、直观地理解Socket通信的数据读写本质。


第 

[标题] 脑残式网络编程入门(三):HTTP协议必知必会的一些知识

[链接] http://www.52im.net/thread-1751-1-1.html

[摘要]无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交道的网络应用层协议之一,它的重要性可能不需要再强调。但是实际上很多人(包括我自己),虽然每天都会跟http的代码打交道,但对http了解的并不够深入。本文就我自己的学习心得,分享一下我认为需要知道的http常见的相关知识点。


第 

[标题] 脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)

[链接] http://www.52im.net/thread-1795-1-1.html

[摘要] 服务器推送(server push)是 HTTP/2 协议里面唯一一个需要开发者自己配置的功能。其他功能都是服务器和浏览器自动实现,不需要开发者关心。本文详细介绍新一代HTTP/2服务器推送技术(server push)的原理和配置方法等。


第 

[标题] 脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?

[链接] http://www.52im.net/thread-1973-1-1.html

[摘要] Ping命令很简单,但作为为数不多的网络检测工具,却非常有用,是开发网络应用时最常用到的命令。虽然“Ping”这个动作这么简单,但你知道Ping命令背后后的逻辑吗?这就是本文要告诉你!


第 

[标题] 脑残式网络编程入门(六):什么是公网IP和内网IP?NAT转换又是什么鬼?

[链接] http://www.52im.net/thread-2082-1-1.html

[摘要] 搞网络通信应用开发的程序员,可能会经常听到外网IP(即互联网IP地址)和内网IP(即局域网IP地址),但他们的区别是什么?又有什么关系呢?另外,内行都知道,提到外网IP和内网IP就不得不提NAT路由转换这种东西,那这又是什么鬼?本文就来简单讲讲这些到底都是怎么回事。


第 

[标题] 脑残式网络编程入门(七):面视必备,史上最通俗计算机网络分层详解

[链接] http://www.52im.net/thread-2851-1-1.html

[摘要] 输入URL,到页面呈现出来,其中经历了什么?这道面试题的背后,涉及到了很多网络原理的知识,我们这篇文章不会全部分享到,而是先把由来和网络层次划分弄清楚,就完成了这篇文章的目的。


第 

[标题] 脑残式网络编程入门(八):你真的了解127.0.0.1和0.0.0.0的区别?

[链接] http://www.52im.net/thread-2928-1-1.html

[摘要] 对于后端程序员来说,127.0.0.1和0.0.0.0这两个IP地址再熟悉不过了,看起来好像就那么回事,但真正较起真来,这两个IP地址到底有什么作用以及到底有什么不同?貌似谁可以轻松回答,但张嘴却又不知从何说起。本文将系统地总结127.0.0.1和0.0.0.0这两个IP地址的作用,以及它们之间的区别,希望能为你解惑。


第 

[标题] 脑残式网络编程入门(九):面试必考,史上最通俗大小端字节序详解

[链接] http://www.52im.net/thread-3101-1-1.html

[摘要] 程序员在写应用层程序时,一般不需要考虑字节序问题,因为字节序跟操作系统和硬件环境有关,而我们编写的程序要么不需要跨平台(比如只运行在windows),要么需要跨平台时会由Java这种跨平台语言在虚拟机层屏蔽掉了。但典型情况,当你编写网络通信程序,比如IM聊天应用时,就必须要考虑字节序问题,因为你的数据在这样的场景下要跨机器、跨网络通信,必须解决不同系统、不同平台的字节序问题。


第 10 

[标题] 网络编程入门从未如此简单(一):假如你来设计网络,会怎么做?

[链接] http://www.52im.net/thread-3330-1-1.html

[摘要] 本篇主要以通俗易懂的文风,引导你理解计算机网络是如何演化成今日的样子,文中穿插了集线器、交换杨、路由器等设备的使用背景以及技术原理,由浅入深,非常适合入门者阅读。


第 11 

[标题] 网络编程入门从未如此简单(二):假如你来设计TCP协议,会怎么做?

[链接] http://www.52im.net/thread-3339-1-1.html

[摘要] 本篇将运用通俗易懂的语言,配上细致精确的图片动画,循序渐进地引导你理解TCP协议的主要特性和技术原理,让TCP协议的学习不再如此枯燥和生涩,非常适合入门者阅读。


第 12 

[标题] 网络编程入门从未如此简单(三):什么是IPv6?漫画式图文,一篇即懂!

[链接] http://www.52im.net/thread-3868-1-1.html

[摘要] 本篇文章将利用简洁生动的文字,配上轻松幽默的漫画,助你从零开始快速建立起对IPv6技术的直观理解,非常适合入门者阅读。

我是Jack Jiang,我为自已带盐!

https://github.com/JackJiang2011/MobileIMSDK/

posted @ 2022-10-18 13:06 Jack Jiang 阅读(120) | 评论 (0)编辑 收藏

关于MobileIMSDK

MobileIMSDK 是一套专门为移动端开发的开源IM即时通讯框架,超轻量级、高度提炼,一套API优雅支持UDP 、TCP 、WebSocket 三种协议,支持iOS、Android、H5、标准Java平台,服务端基于Netty编写。

工程开源地址是:

关于RainbowChat

► 详细产品介绍:http://www.52im.net/thread-19-1-1.html
► iOS端更新记录:http://www.52im.net/thread-2735-1-1.html
► 全部运行截图:iOS端全部运行截图 (另:Android端运行截图 点此查看
► 在线体验下载:App Store安装地址 (另:Android端下载体验 点此查看

 

RainbowChat是一套基于开源IM聊天框架 MobileIMSDK 的产品级移动端IM系统。RainbowChat源于真实运营的产品,解决了大量的屏幕适配、细节优化、机器兼容问题(可自行下载体验:专业版下载安装)。

RainbowChat可能是市面上提供im即时通讯聊天源码的,唯一一款同时支持TCP、UDP两种通信协议的IM产品(通信层基于开源IM聊天框架  MobileIMSDK 实现)。

v6.0 版更新内容

此版更新内容新增“一键已读、搜索”等功能!】(更多历史更新日志):

  • 1)[新增] 搜索功能(支持好友、群聊、聊天记录搜索(与微信逻辑一样));
  • 2)[新增] “聊天信息”界面中新增“查找聊天记录”功能;
  • 3)[新增] “群聊信息”界面中新增“查找聊天记录”功能;
  • 4)[新增] 首页消息界面中,增加了“一键已读”功能;
  • 5)[bug] 解决了iOS16+“灵动岛”手机下,聊天界面功能面板和输入法显示的冲突;
  • 6)[优化] 优化了聊天界面中查看位置、名片消息回来时会自动滚动到最后一行的问题。

此版主要新增功能运行截图更多截图点此查看):

posted @ 2022-10-12 15:01 Jack Jiang 阅读(92) | 评论 (0)编辑 收藏

     摘要: 本文由vivo技术团队Yang Kun分享,原题“electron 应用开发优秀实践”,即时通讯网有修订。1、引言在上篇《Electron初体验(快速开始、跨进程通信、打包、踩坑等)》的分享中,我们已经对Electron跨端框架的开发有了大概的了解。本篇将基于vivo技术团队的技术实践,详细阐述了vivo在使用Electron进行跨端桌面开发时的技术栈选型考量,同时分享了在...  阅读全文

posted @ 2022-10-08 10:16 Jack Jiang 阅读(142) | 评论 (0)编辑 收藏

为了更好地分类阅读总计1000多篇精编文章,我将在每周三推送新的一期技术文集,本次是第1 期。

[标题] 网络编程懒人入门(一):快速理解网络通信协议(上篇)

[链接] http://www.52im.net/thread-1095-1-1.html

[摘要] 互联网的核心是一系列协议,总称为"互联网协议"(Internet Protocol Suite)。它们对电脑如何连接和组网,做出了详尽的规定。理解了这些协议,就理解了互联网的原理。本篇将带你从理论上快速理解这些协议。


[标题] 网络编程懒人入门(二):快速理解网络通信协议(下篇)

[链接] http://www.52im.net/thread-1103-1-1.html

[摘要] 接上篇,本篇将以普通人实际上网为例子,通俗易懂地讲解网络通信协议到底是什么。本篇带了有些基础的计网理论知识,但力求通俗不枯燥。


[标题]网络编程懒人入门(三):快速理解TCP协议一篇就够

[链接]http://www.52im.net/thread-1107-1-1.html

[摘要] TCP 是互联网的核心协议之一,鉴于它的重要性,本文将单独介绍它的基础知识,希望能加深您对TCP协议的理解。


[标题]网络编程懒人入门(四):快速理解TCP和UDP的差异

[链接]http://www.52im.net/thread-1160-1-1.html

[摘要] 对于即时通讯开者新手来说,在开始着手编写IM或消息推送系统的代码前,最头疼的问题莫过于到底该选TCP还是UDP作为传输层协议。本文延续《网络编程懒人入门》系列文章的风格,通过快速对比分析 TCP 和 UDP 的区别,来帮助即时通讯初学者快速了解这些基础的知识点,从而在IM、消息推送等网络通信应用场景中能准确地选择合适的传输层协议。


[标题]网络编程懒人入门(五):快速理解为什么说UDP有时比TCP更有优势

[链接]http://www.52im.net/thread-1277-1-1.html

[摘要] 随着网络技术飞速发展,网速已不再是传输的瓶颈,UDP协议以其简单、传输快的优势,在越来越多场景下取代了TCP,如网页浏览、流媒体、实时游戏、物联网。本文作为《网络编程懒人入门》系列文章的第5篇,将为您快速梳理UDP协议在某些场景下对比TCP协议所具有的优势。


[标题]网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门

[链接]http://www.52im.net/thread-1629-1-1.html

[摘要] 本文旨在简单地说明集线器、交换机与路由器的区别,因而忽略了很多细节,三者实际的发展过程和工作原理并非文中所写的这么简单。如果你看完本文能大概了解到三者的异同,本文的目的就达到了。


[标题] 网络编程懒人入门(七):深入浅出,全面理解HTTP协议

[链接] http://www.52im.net/thread-1677-1-1.html

[摘要] 对于移动端即时通讯(尤其IM应用)来说,现今主流的数据通信总结下来无外乎就是长连接+短连接的方式,而短连接在应用上讲就是本文将要介绍的HTTP协议的应用,而正确地理解HTTP协议对于写好IM来说,是相当有益的(关于移动端的HTTP具体应用情况,可以阅读《现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障http://www.52im.net/thread-1413-1-1.html》)。


[标题] 网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接

[链接] http://www.52im.net/thread-1722-1-1.html

[摘要] TCP 是互联网的核心协议之一,鉴于它的重要性,希望通过阅读上面介绍的几篇理论文章,再针对本文的动手实践,能真正加深您对TCP协议的理解。


[标题] 网络编程懒人入门(九):通俗讲解,有了IP地址,为何还要用MAC地址?

[链接] http://www.52im.net/thread-2067-1-1.html

[摘要] 标题虽然是为了解释有了 IP 地址,为什么还要用 MAC 地址,但是本文的重点在于理解为什么要有 IP 这样的东西。本文对读者的定位是知道 MAC 地址是什么,IP 地址是什么。


10 

[标题] 网络编程懒人入门(十):一泡尿的时间,快速读懂QUIC协议

[链接]http://www.52im.net/thread-2816-1-1.html

[摘要] 一般的稳定网络传输都是通过TCP,但是在网络基建本身就已经越来越完善的情况下,TCP设计本身的问题便暴露了出来,特别是在弱网环境下,让我们不得不考虑一些新的可能性。


11 

[标题] 网络编程懒人入门(十一):一文读懂什么是IPv6

[链接]http://www.52im.net/thread-2979-1-1.html

[摘要] 本文将用浅显易懂的文字,带你了解到底什么是IPv6。


12 

[标题]网络编程懒人入门(十二):快速读懂Http/3协议,一篇就够!

[链接]http://www.52im.net/thread-3020-1-1.html

[摘要] 多年来,为了跟上互联网的发展,以及WWW上交换的内容种类增加,HTTP进行了几次重大升级,而HTTP/3就是目前的最新版本。本文将从HTTP/3的基本概念、技术原理、应用场景和如何使用它等方面进行介绍,确保在有限的篇幅内,能让你通俗地理解它。


13 

[标题]网络编程懒人入门(十三):一泡尿的时间,快速搞懂TCP和UDP的区别

[链接]http://www.52im.net/thread-3793-1-1.html

[摘要] 不同于其它长篇大论,本文尽量以简洁精炼的文字,帮你总结归纳TCP和UDP协议的主要区别,方便那些想掌握这方面知识又不愿意耗费太多时间去系统地学习网络理论基础的同学快速理解!


14 

[标题]网络编程懒人入门(十四):到底什么是Socket?一文即懂!

[链接] http://www.52im.net/thread-3821-1-1.html

[摘要] 本系列文章前面那些主要讲解的是计算机网络的理论基础,但对于即时通讯IM这方面的应用层开发者来说,跟计算机网络打道的其实是各种API接口。本篇文章就来聊一下网络应用程序员最熟悉的Socket这个东西,抛开生涩的计算机网络理论,从应用层的角度来理解到底什么是Socket。

我是Jack Jiang,我为自已带盐!

https://github.com/JackJiang2011/MobileIMSDK/

posted @ 2022-10-08 10:16 Jack Jiang 阅读(102) | 评论 (0)编辑 收藏

     摘要: 本文由蘑菇街前端技术团队分享,原题“Electron 从零到一”,有修订和改动。1、引言在上篇《快速了解新一代跨平台桌面技术——Electron》,我们已经对Electron跨端框架有了基本的认识。本篇将带你简单上手Electron框架开发跨平台桌面端,内容包括一个快速开始例子、跨进程通信原理、打包和分发、以及一些典型的技术踩坑等。希望能带给你启发。...  阅读全文

posted @ 2022-09-22 11:10 Jack Jiang 阅读(171) | 评论 (0)编辑 收藏

关于MobileIMSDK

MobileIMSDK 是一套专门为移动端开发的开源IM即时通讯框架,超轻量级、高度提炼,一套API优雅支持UDP 、TCP 、WebSocket 三种协议,支持iOS、Android、H5、标准Java平台,服务端基于Netty编写。

工程开源地址是:

关于RainbowChat

► 详细产品介绍:http://www.52im.net/thread-19-1-1.html
► iOS端更新记录:http://www.52im.net/thread-2735-1-1.html
► 全部运行截图:iOS端全部运行截图 (另:Android端运行截图 点此查看
► 在线体验下载:App Store安装地址 (另:Android端下载体验 点此查看

 

RainbowChat是一套基于开源IM聊天框架 MobileIMSDK 的产品级移动端IM系统。RainbowChat源于真实运营的产品,解决了大量的屏幕适配、细节优化、机器兼容问题(可自行下载体验:专业版下载安装)。

RainbowChat可能是市面上提供im即时通讯聊天源码的,唯一一款同时支持TCP、UDP两种通信协议的IM产品(通信层基于开源IM聊天框架  MobileIMSDK 实现)。

v5.0 版更新内容

此版更新内容【新增“扫一扫”等功能更多历史更新日志):

  • 1)[新增] “扫一扫”界面及功能逻辑;
  • 2)[新增] “我的二维码”界面及功能逻辑;
  • 3)[新增] “群聊二维码”界面及功能逻辑;
  • 4)[优化] 相关界面中的弹出菜单UI细节优化。

此版主要新增功能运行截图更多截图点此查看):

posted @ 2022-09-14 22:59 Jack Jiang 阅读(96) | 评论 (0)编辑 收藏

     摘要: 本文由微信客户端技术团队工程师“Jon”分享,原题“Windows微信:消息数据库架构演进”,有较多修订。1、引言本文分享的是,微信客户端团队基于对微信用户日常使用场景和数据分析,通过分离重要和非重要数据、采用可靠的分库策略等,对微信Windows端IM本地数据库的架构进行的优化和改造,并最终得到一个具备良好实践效果的技术改造方案。 以下是...  阅读全文

posted @ 2022-09-05 11:50 Jack Jiang 阅读(132) | 评论 (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 阅读(94) | 评论 (0)编辑 收藏

仅列出标题
共47页: First 上一页 13 14 15 16 17 18 19 20 21 下一页 Last 
Jack Jiang的 Mail: jb2011@163.com, 联系QQ: 413980957, 微信: hellojackjiang