【翻译】WhatsApp 加密概述(技术白皮书)
简介
本白皮书提供了 WhatsApp 端到端加密系统的技术说明。请访问 WhatsApp 的网站 www.whatsapp.com/security 了解更多。
WhatsApp Messenger 允许人们自由的交换消息(包括聊天,群聊,图片,视频,语音消息和文件),并在发送者和接收者之间使用端对端加密(在 2016 年 3 月 31 之后的版本)。
Signal 协议是由 Open Whisper Systems (非盈利软件开发团体)设计,是 WhatsApp 端对端加密的基础。这种端对端加密协议旨在防止第三方和 WhatsApp 对消息或通话进行明文访问。更重要的是,即使用户设备的密钥泄露,也不能解密之前传输的消息。
本文档概述了 Singal 协议在 WhatsApp 中的应用。
- 身份密钥对(Identity Key Pair) —— 一个长期 Curve25519 密钥对,安装时生成。
- 已签名的预共享密钥(Signed Pre Key) —— 一个中期 Curve25519 密钥对,安装时生成,由身份密钥签名,并定期进行轮换。
- 一次性预共享密钥(One-Time Pre Keys) —— 一次性使用的 Curve25519 密钥对队列,安装时生成,不足时补充。
- 根密钥(Root Key) —— 32 字节的值,用于创建链密钥。
- 链密钥(Chain Key) —— 32 字节的值,用于创建消息密钥。
- 消息密钥(Message Key) —— 80 个字节的值,用于加密消息内容。32 个字节用于 AES-256 密钥,32 个字节用于 HMAC-SHA256 密钥,16 个字节用于 IV。
- 会话发起人为接收人申请身份公钥(public Identity Key)、已签名的预共享公钥(public Signed Pre Key)和一个一次性预共享密钥(One-Time Pre Key)。
- 服务器返回所请求的公钥。一次性预共享密钥(One-Time Pre Key)仅使用一次,因此请求完成后将从服务器删除。如果一次性预共享密钥(One-Time Pre Key)被用完且尚未补充,则返回空。
- 发起人将接收人的身份密钥(Identity Key)存为 Irecipient,将已签名的预共享密钥(Signed Pre Key)存为 Srecipient,将一次性预共享密钥(One-Time Pre Key)存为 Orecipient。
- 发起者生成一个临时的 Curve25519 密钥对 —— Einitiator
- 发起者加载自己的身份密钥(Identity Key)作为 Iinitiator
- 发起者计算主密钥 master_secret = ECDH ( Iinitiator, Srecipient ) || ECDH ( Einitiator, Irecipient ) || ECDH ( Einitiator, Srecipient ) || ECDH ( Einitiator, Orecipient ) 。如果没有一次性预共享密钥(One-Time Pre Key),最终 ECDH 将被忽略。
- 发起者使用 HKDF 算法从 master_secret 创建一个根密钥(Root Key)和链密钥(Chain Keys)。
- 接收人使用自己的私钥和消息 header 里的公钥来计算相应的主密钥
- 接收人删除发起人使用的一次性预共享密钥(One-Time Pre Key)
- 发起人使用 HKDF 算法从主密钥派生出相应的根密钥(Root Key)和链密钥(Chain Keys)
交换消息
一旦建立了会话,通过 AES256 消息密钥加密(CbC 模式)和 HMAC-SHA256 验证来保护客户端交换消息。
消息密钥是短暂的且在每次发送消息后都会变化,使得用于加密消息的消息密钥不能从已发送或已接收后的会话状态中重建。
消息密钥在发送消息时对发送人的链密钥(Chain Key)进行向前的“棘轮(ratchets)”派生而来。此外,每次消息巡回都执行一个新的 ECDH 协议以创建一个新的链密钥(Chain Key)。通过组合即时 “哈希棘轮(hash ratchet)” 和巡回 “DH 棘轮(DH ratchet)” 提供前向安全。
通过链密钥(Chain Key)计算消息密钥(Message Key)
消息发送者每次需要新的消息密钥时,计算如下:
- 消息密钥(Message Key)= HMAC-SHA256(Chain Key, 0x01)
- 链密钥(Chain Key)随后更新为: 链密钥(Chain Key) = HMAC-SHA256(Chain Key, 0x02)
这样形成向前“棘轮(ratchets)”链密钥(Chain Key),这也意味不能使用存储的消息密钥推导出当前或过去的链密钥(Chain Key)值。
通过根密钥(Root Key)计算链密钥(Chain Key)
每一条发送的消息都附带一个短期的 Curve25519 公钥。一旦收到响应,新的链密钥(Chain Key)计算如下:
- ephemeral_secret = ECDH(Ephemeralsender, Ephemeralrecipient)
- 链密钥(Chain Key),根密钥(Root Key)= HKDF(Root Key, ephemeral_secret)
一个链密钥只能给一个用户发消息,所以消息密钥不能被重用。由于消息密钥和链密钥(Chain Keys)的计算方式,消息可能会延迟、乱序或完全丢失而不会有问题。
传输媒体和附件
任何类型的大附件(视频,音频,图像或文件)也都是端对端加密的:
- 发件人(发消息的 WhatsApp 用户)生成一个 32 字节的 AES256 临时密钥和一个 32 字节HMAC-SHA256 临时密钥。
- 发件人通过 AES256 密钥(CBC 模式)和随机 IV 给附件加密,然后附加使用 HMAC-SHA256 密文的 MAC。
- 发件人将加密的附件以上传到服务器以二进制存储。
- 发件人给收件人发送一个包含加密密钥、HMAC 密钥、加密二进制的 SHA256 哈希值和指向二进制存储的指针的加密消息
- 收件人解密消息,从服务器检索加密的二进制数据,验证 AES256 哈希,验证 MAC并解密为明文。
群组消息
传统未加密的聊天应用通常对群组消息使用“服务器扇出(server-side fan-out)”来发群组消息。当一个用户向群组发消息时,服务器将消息分发给每一个群组成员。
而“客户端扇出(client-side fan-out)”是客户端将消息发给每一个群组成员。
WhatsApp 的群组消息基于上面列出的成对加密会话构建,以便高效实现大量群组消息通过服务器扇出(server-side fan-out)。这是通过 Signal 传输协议(Signal Messaging Protocol)的 “发送者密钥(Sender Keys)”来完成的。
WhatsApp 群组成员第一次发消息到群组:
- 发送人生成一个随机 32 字节的链密钥(Chain Key)。
- 发送人生成一个随机 Curve25519 签名密钥对。
- 发送人将 32 位链密钥(Chain Key)和签名密钥中的公钥组合成消息发送人密钥(Sender Key)。
- 发件人用成对传输协议为每个群组成员单独加密发送人密钥(Sender Keys)。
所有后续发给该群组的消息:
- 发送人从链密钥(Chain Key)中获取消息密钥(Message Key)并更新链密钥(Chain Key)
- 发送人在 CbC 模式下使用 AES256 加密消息
- 发送人使用签名密钥(Signature Key)签名密文
- 发送人将单个密文消息发给服务器,服务器将消息分发给所有群组成员
消息发送人链密钥(Chain Key)的“哈希棘轮(hash ratchet)”提供向前安全。当群组成员离开时时,所有剩下的群组成员都清除发送人密钥(Sender Key)并重新生成。
通话设置
WhatsApp 语音和视频通话也是端对端加密。当 WhatsApp 用户发起语音或视频通话时:
- 发起人与接收人建立加密会话(如果还没有建立过)
- 发起人生成一个随机 32 字节的安全实时传输协议(SRTP) 主密钥(master secret)
- 发起人向接收人发送一个包含安全实时传输协议(SRTP)主密钥的加密消息用于发通话信号
- 如果应答了呼叫,跟着发起安全实时传输协议(SRTP)呼叫
状态
WhatsApp 状态加密方式和群组消息非常相似。给指定的一组接收人第一次发状态遵循向群组第一次发消息相同的步骤。类似地,给同一组接收人发送后续状态也遵循发群组消息相同的步骤。当状态发送人更改状态隐私设置或从地址簿种删除号码来删除接收人时,状态发送人会清除发送人密钥(Sender Key)并重新生成。
验证密钥
WhatsApp 用户还可以验证与之通信用户的密钥,以便他们能够确认未授权的第三方(或 WhatsApp)未发起中间人攻击。通过扫描二维码或通过比较 60 位数字来完成。
二维码包括:
- 版本号
- 双方的用户身份
- 双方完整的 32 字节身份公钥
当用户扫描对方的二维码时,将比较这些密钥以确保二维码中的身份密钥与服务器检索到的相匹配。
通过拼接两个用户身份密钥的 30 位数字指纹来计算 60 位数字号码。计算 30 位数字指纹步骤:
- 重复 SHA-512 哈希身份公钥和用户标识符 5200 次
- 获取最后输出哈希的前 30 个字节
- 将 30 个字节分成 6 组每组 5 字节的数据块
- 通过解析每组 5 字节数据块为 big-endian 无符号整形并且取模 10 万次转换为 5 个数字
- 把六组每组 5 个数字连接成 30 位数字
传输安全
WhatsApp 客户端和服务器之间所有通信都在单独的加密通道内分层。在 Windows Phone、iPhone 和 Android 上,这些端对端加密客户端可以使用噪音管道(Noise Pipes),使用噪声协议框架(Noise Protocol Framework)中的 Curve25519、AES-GCM 和 SHA256 实现长期运行的交互连接。
这为客户端提供了一些不错的属性:
- 极快的轻量级连接设置和恢复
- 加密隐藏元数据防止未授权的网络监听。没有透露连接用户身份相关的信息。
- 服务器上不存储客户端的安全认证信息。客户端使用 Curve25519 密钥进行身份验证,因此服务器仅保存客户端认证公钥(public authentication key)。如果服务器的用户数据库被入侵,也不会泄露个人认证凭证。
结论
WhatsApp 用户之间的消息受到端对端加密协议的保护,因此第三方和 WhatsApp 都无法获知消息内容,消息只能由接收人解密。所有 WhatsApp 消息(包括聊天、群聊、图片、视频、语音消息和文件)和 WhatsApp 通话都受到端对端加密的保护。
WhatsApp 服务器无法访问 WhatsApp 用户的私钥,并且 WhatsApp 用户可以选择验证密钥以确保其通讯完整。
WhatsApp 使用的 Signal 协议库是开源的,代码:https://github.com/whispersystems/libsignal-protocol-java/
参考
过年期间翻译了一下,本来英语就差非常吃力,正好做这块硬着头皮试着翻译一下,希望对英语也不好的朋友有一点帮助。对了,招人,看我博客首页招 Swifter :)
【翻译】WhatsApp 加密概述(技术白皮书)的更多相关文章
- [华三] IPv6技术白皮书(V1.00)
IPv6技术白皮书(V1.00) http://www.h3c.com/cn/d_200802/605649_30003_0.htm H3C S7500E IPv6技术白皮书 关键词:IPv6,隧道 ...
- SSL技术白皮书
首页产品技术操作系统ComwareV5安全和VPN SSL技术白皮书 下载 收藏 打印 推荐 摘自:http://www.h3c.com/cn/d_200812/622834_30003_0.htm# ...
- [破解] DRM-内容数据版权加密保护技术学习(上):视频文件打包实现
1. DRM介绍: DRM,英文全称Digital Rights Management, 可以翻译为:内容数字版权加密保护技术. DRM技术的工作原理是,首先建立数字节目授权中心.编码压缩后的数字节目 ...
- Isolate-user-vlan技术白皮书
http://www.h3c.com.cn/Products___Technology/Technology/LAN/Other_technology/Technology_book/200804/6 ...
- DMR技术白皮书
DMR技术白皮书 主页(http://pttcn.net):DMR技术白皮书 关于DMR 1.模拟技术的局限性 虽然模拟技术仍具有不少优势,如低廉的成本.可自定的功能以及简便的搭建方式等.但模拟技术已 ...
- PPPoE技术白皮书(H3C)
PPPoE技术白皮书 关键词:PPP,Ethernet,PPPoE 摘要:PPPoE是一种通过一个远端接入设备为以太网上的主机提供接入服务,并可以对接入的每个主机实现控制和计费的技术.本文介绍了PPP ...
- URPF技术白皮书
URPF技术白皮书 摘 要:本文介绍了URPF的应用背景,URPF主要用于防止基于源地址欺骗的网络攻击行为,例如基于源地址欺骗的DoS攻击和DDoS攻击:随后介绍了URPF的技术原理以及URPF ...
- python爬虫-有道翻译-js加密破解
有道翻译-js加密破解 这是本地爬取的网址:http://fanyi.youdao.com/ 一.分析请求 我们在页面中输入:水果,翻译后的英文就是:fruit.请求携带的参数有很多,先将参数数据保存 ...
- JAP 1.0.1 以及 《JAP产品技术白皮书》正式发布
快讯 JAP 1.0.1 正式发布 <JAP产品技术白皮书>正式发布.立即获取:白皮书 JAP 1.0.1 版本内容 新增功能/支持 添加 com.fujieid.jap.core.uti ...
随机推荐
- Python机器学习笔记 异常点检测算法——Isolation Forest
Isolation,意为孤立/隔离,是名词,其动词为isolate,forest是森林,合起来就是“孤立森林”了,也有叫“独异森林”,好像并没有统一的中文叫法.可能大家都习惯用其英文的名字isolat ...
- MVC Scaffolding SmartCode-Engine 更新
概述 通过扩展visual studio.net scaffolding组件,添加了一套功能完善的代码模板,包括Controller,Model,View,Businessd等各种功能的代码,配合En ...
- 如何正确使用Java泛型
前言 Java 1.5之前是没有泛型的,以前从集合中读取每个对象都必须先进行转换,如果不小心存入集合中对象类型是错的,运行过程中转换处理会报错.有了泛型之后编译器会自动帮助转换,使程序更加安全,但是要 ...
- DSAPI之摄像头追踪指定颜色物体
Private CAM As New DSAPI.摄像头_avicap32 Private Clr As Color = Color.FromArgb(230, 50, 50) Private _Lo ...
- aps.net core mvc中使用session
原因>>用session是想验证 前端输入的验证码和后端存入seesion的是否一致,也可以使用的是TempData[]. 铺垫>> 前端用GetValidateCode()方 ...
- Web.config中customErrors异常信息配置
开发工具:Visual Studio 2017 15.7.5 开发平台:Windows 10 新建WebApi项目,Web.config配置文件中,system.web下级节点中默认没有customE ...
- Android安全——加固原理
一.前言 今天来介绍一下Android中的如何对Apk进行加固的原理.现阶段.我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk,结果被人反编译了,那心情真心不舒服.虽 ...
- string[]转list<long>,List转字符串
List转字符串,用逗号隔开 List<string> list = new List<string>();list.Add("a");list.Add(& ...
- JavaScript 为什么要有 Symbol 类型?
Symbols 是 ES6 引入了一个新的数据类型 ,它为 JS 带来了一些好处,尤其是对象属性时. 但是,它们能为我们做些字符串不能做的事情呢? 在深入探讨 Symbol 之前,让我们先看看一些 J ...
- 震惊!Vector两行代码求逆序对,六行代码过普通平衡树
Vector两行代码求逆序对 背景:济南集训Day7上午T2,出了一道逆序对的裸题,SB的我没看出是逆序对来,于是现场推了一个很刁钻的求逆序对的方法 首先我们想一下冒泡排序的过程,我们不难发现,对于每 ...