在注册时,WhatsApp客户端将身份公钥(publicIdentityKey)、已签名的预共享公钥(publicSignedPreKey)和一批一次性预共享公钥(One-TimePreKeys)发送给服务器。WhatsApp服务器存储用户身份相关的公钥。WhatsApp服务器无法访问任何客户端的私钥。
会话初始化设置
要与另一个WhatsApp用户通信,WhatsApp 客户端需要先建立一个加密会话。加密会话一旦被创建,客户端就不需要再重复创建会话,除非会话失效(例如重新安装应用或更换设备)。
建立会话:
接收会话设置
在建立长期加密会话后,发起人可以立即向接收人发送消息,即使接收人处理离线状态。在接收方响应之前,发起方所有的消息都会包含创建会话所需的信息(在消息的 header 里)。其中包括发起人的 Einitiator 和 Iinitiator。当接收方收到包含会话设置的消息时:
交换消息
一旦建立了会话,通过 AES256 消息密钥加密(CbC 模式)和 HMAC-SHA256 验证来保护客户端交换消息。消息密钥是短暂的且在每次发送消息后都会变化,使得用于加密消息的消息密钥不能从已发送或已接收后的会话状态中重建。消息密钥在发送消息时对发送人的链密钥(ChainKey)进行向前的“棘轮(ratchets)”派生而来。此外,每次消息巡回都执行一个新的 ECDH 协议以创建一个新的链密钥(ChainKey)。通过组合即时“哈希棘轮(hash ratchet)”和巡回“DH 棘轮(DH ratchet)”提供前向安全。
通过链密钥(ChainKey)计算消息密钥(MessageKey)
消息发送者每次需要新的消息密钥时,计算如下:
这样形成向前“棘轮(ratchets)”链密钥(ChainKey),这也意味不能使用存储的消息密钥推导出当前或过去的链密钥(ChainKey)值。
通过根密钥(RootKey)计算链密钥(ChainKey)
每一条发送的消息都附带一个短期的 Curve25519 公钥。一旦收到响应,新的链密钥(ChainKey)计算如下:
一个链密钥只能给一个用户发消息,所以消息密钥不能被重用。由于消息密钥和链密钥(ChainKeys)的计算方式,消息可能会延迟、乱序或完全丢失而不会有问题。
传输媒体和附件
任何类型的大附件(视频,音频,图像或文件)也都是端对端加密的:
群组消息
传统未加密的聊天应用通常对群组消息使用“服务器扇出(server-side fan-out)”来发群组消息。当一个用户向群组发消息时,服务器将消息分发给每一个群组成员。而“客户端扇出(client-side fan-out)”是客户端将消息发给每一个群组成员。WhatsApp 的群组消息基于上面列出的成对加密会话构建,以便高效实现大量群组消息通过服务器扇出(server-side fan-out)。这是通过 Signal 传输协议(Signal Messaging Protocol)的“发送者密钥(SenderKeys)”来完成的。WhatsApp 群组成员第一次发消息到群组:
所有后续发给该群组的消息:
消息发送人链密钥(ChainKey)的“哈希棘轮(hash ratchet)”提供向前安全。当群组成员离开时时,所有剩下的群组成员都清除发送人密钥(SenderKey)并重新生成。
通话设置
WhatsApp 语音和视频通话也是端对端加密。当 WhatsApp 用户发起语音或视频通话时:
状态
WhatsApp 状态加密方式和群组消息非常相似。给指定的一组接收人第一次发状态遵循向群组第一次发消息相同的步骤。类似地,给同一组接收人发送后续状态也遵循发群组消息相同的步骤。当状态发送人更改状态隐私设置或从地址簿种删除号码来删除接收人时,状态发送人会清除发送人密钥(SenderKey)并重新生成。
验证密钥
WhatsApp 用户还可以验证与之通信用户的密钥,以便他们能够确认未授权的第三方(或 WhatsApp)未发起中间人攻击。通过扫描二维码或通过比较 60 位数字来完成。二维码包括:
当用户扫描对方的二维码时,将比较这些密钥以确保二维码中的身份密钥与服务器检索到的相匹配。通过拼接两个用户身份密钥的 30 位数字指纹来计算 60 位数字号码。计算 30 位数字指纹步骤:
传输安全
WhatsApp客户端和服务器之间所有通信都在单独的加密通道内分层。在Windows Phone、iPhone和Android上,这些端对端加密客户端可以使用噪音管道(Noise Pipes),使用噪声协议框架(Noise Protocol Framework)中的Curve25519、AES-GCM和SHA256实现长期运行的交互连接。这为客户端提供了一些不错的属性:
结论
WhatsApp用户之间的消息受到端对端加密协议的保护,因此第三方和WhatsApp都无法获知消息内容,消息只能由接收人解密。所有WhatsApp消息(包括聊天、群聊、图片、视频、语音消息和文件)和WhatsApp通话都受到端对端加密的保护。WhatsApp服务器无法访问WhatsApp用户的私钥,并且WhatsApp用户可以选择验证密钥以确保其通讯完整。WhatsApp使用的Signal协议库是开源的。
whatsapp协议简单分析
whatsapp主要采用XMPP协议来做数据包组织。那么从XMPP的几个要点来分析whatsapp的协议。
出席(presence)
出席通知其他实体的网络可用性,并且使你能够知道其他实体是否在线和可用于通讯。它是一个在互联网上沟通和合作的催化剂,因为人们更容易与你交流,如果他们知道你是否在线。只有通过你授权的人才能看到你是否在线。这个授权被称为出席订阅。当你在线时,你向你的服务器宣告你的出席,然后服务器将你在线通知告诉你的联系人,并且获得他们的当前出席显示在你的客户端界面上。
那么在whatsapp上如何实现这些了?
自己出席:
订阅用户请求:
订阅用户响应:
用户上线通知:
查询(iq)
查询(IQ)节提供了一种用于请求-应答交互和简单工作流的结构.
和节不同,一个IQ节能包含仅有一个有效载荷,用于定义处理的请求或接收人采用的行为。
发送IQ节的实体必须总是接收一个回复(通常由目的接收者或接受者的服务器产生)。
请求和应答通过使用id属性跟踪,id属性由请求实体生成,并被包含在应答的实体中
信息/查询type
那么在whatsapp上的一些实际例子。
心跳请求:
心跳响应:
获取缩略图请求:
获取缩略图响应:
信息(ib)
信息(IB)节提供了服务器主动推送一些配置信息,客户端无需回复。在whatsapp上的一些实际例子。
通知离线消息数量
通知路由信息
【4】08080802 【2】6662
消息
节是使用基本的“push”方法从一个地方到另一个地方得到消息,消息是不可告知的,它是一种“fire-and-forget”的机制从一个地方到另一个地方快速获取信息。
消息的type
消息的 to: 预期收件人的 Jabber ID
消息的 from: 发送者的 Jabber ID,from 地址不由发送客户端提供,而是由发送者的服务器添加邮戳,以避免地址欺骗。
消息也包含有载荷元素。核心 XMPP 规格定义了一些非常基本的有效载荷,例如 和 ,被用于人对人的聊天信息, 消息(和其他类的节)可以包含在核心 XMPP 规格中没有定义的有效载荷
在 whatsapp 上的一些实际例子。
新消息:
3308a1bdba970310051a5092600d3053b8dc373f68896ff2dec4e0fe9d6e0ffe1a34438e11f8510b9dd693762de8372e2b201aca6f789dc62690acaeb61d839d350872f1be4799569e833795a67a69374a78500852ddd208d1bf0d3dbeb48f31e61f8b3d18e4199e36dda7f50ac72aabdded1cf2006aafa4db366a8e207bf4a82bdd3df0f58b6dee518c703bb1495f3a3d4b7fc401458da0f90f06
消息到达:
参考链接:
相关文章:即时通讯协议之XMPPPEP 484:类型提示 Type HintsMicrosoft REST API Guidelines中文翻译
版权声明
本文仅代表作者观点,不代表xx立场。
本文系作者授权xx发表,未经许可,不得转载。
最新留言