WhatsApp 如何恢复本地或 Google 云端硬盘备份?

信息安全 密钥管理 备份 whatsapp
2021-08-23 04:36:34

这与他们的端到端传输协议无关,我的问题主要以 Android 为中心。

我问自己:在阅读有关破解和解密本地 WhatsApp 数据库备份的信息时,有人提到 Android 需要受限应用程序区域中的私钥。如果您没有 root 手机,您通常不应访问此密钥。如果没有此密钥,备份文件(文件扩展名 crypt5-12)通常是无用的。

当您切换手机(例如购买新手机)时,您可以将本地sdcard/WhatsApp文件夹复制到新手机,如果使用相同的号码,WhatsApp 可以解密该备份:来源在这里https://www.whatsapp.com/faq/en /android/20887921#restore

第一个假设:备份密钥也保存在 WhatsApp 服务器上。否则本地电话到电话备份将不起作用?

第二个假设:因此,最糟糕的是,如果您在 Google Drive 上备份,WhatsApp 理论上可以访问(?)您的(希望是加密的)备份,还可以访问其服务器上的加密/解密密钥。或者至少在 WhatsApp 本身无法读取的 Google Drive 之间存在区别?有人有更多细节吗?

关于端对端加密协议的最后一句话:当您的至少一个朋友对他们的聊天进行 Google Drive 备份(聊天历史可检索)时,这似乎是无用的(不是针对普通黑客,但我认为针对美国的监视)。

2个回答

第一个假设:备份密钥也保存在 WhatsApp 服务器上。否则本地电话到电话备份将不起作用?

TL;DR:是的,经过一番调查,情况似乎如此。

辅助设备

该协议相当复杂,不仅限于WhatsApp,但通常是这样工作的;使用聊天应用程序的手机称为第一台设备该设备是存储所有敏感数据的万能设备,如私人身份密钥、连接密码、本地加密密钥、附件加密密钥等。所有其他设备称为第二设备,包括 WhatsApp 网络和桌面客户端。这些客户本质上是愚蠢的。

每当出现新设备时,都需要先通过第一台设备对其进行身份验证。WhatsApp 使用初始 QR 码(其他应用程序使用 SMS 令牌)然后通过一组证明来执行此操作。最终,第一个设备决定是否允许辅助设备控制敏感数据。如果是这样,则第二个设备应请求接收这些密钥。使用这些密钥,第二个设备可以下载联系人文件并使用请求的密钥对其进行解密。同样适用于所有媒体消息。针对 WhatsApp 的特殊说明:这些密钥请求的时间很短,因此需要辅助客户端定期向第一个设备请求新密钥以访问数据。这会导致烦人的 '电话未连接' WhatsApp 网页中的警报。

每当您在新手机上安装 WhatsApp 时,整个过程都会发生,第一台设备将授权新手机并立即锁定两个活动实例中的一个。然后,您可以选择其中一部手机。如果您选择新手机,所有秘密的所有权将转移到第二台设备,然后成为完成圈子的第一台设备。

备份

经过一些调查、反编译应用程序和运行测试场景后,我们可以进行以下操作: 该应用程序正在使用多个本地 (SQLite) 数据库。消息未加密地存储在这些数据库中,数据库本身也未加密。您可以通过从 data/ 文件夹下载 .db 文件自行检查。这是 WhatsApp 在运行模式下的默认存储位置,很可能出于性能原因未加密。普通应用程序应该无法访问数据文件夹中的 .db 文件,但有很多adb解决方法。

包括设置和消息在内的数据库文件会在 Google Drive 中备份(如果您选择这样做)。该应用程序可以请求锁定 Google Drive 中的文件夹,以防止用户下载或访问备份。发送到远程备份位置的消息数据库是msgstore.db.crypt[0-12]文件,其中最后一个数字表示协议版本。数据库使用存储在数据文件夹中的密钥进行加密。此密钥实际上存储在 WhatsApp 服务器上。

第二个假设:因此,最糟糕的是,如果您在 Google Drive 上备份,WhatsApp 理论上可以访问(?)您的(希望是加密的)备份,还可以访问其服务器上的加密/解密密钥。或者至少在 WhatsApp 本身无法读取的 Google Drive 之间存在区别?有人有更多细节吗?

当您安装新设备并设置您的 Google 帐户时,应用程序可以请求文件并在本地设备上进行配置。这包括 axolotl 数据库,其中包含向他人证明您的身份所必需的身份密钥。在向新安装的 WhatsApp 实例证明电话号码(用户名)的所有权后,将检索解密密钥。理论上,WhatsApp 应该无法访问这些文件,而只能访问您和 Google。当然,WhatsApp 可以下载文件并将它们发送到另一个位置。但在某些时候,我们需要信任应用程序,特别是如果它不是开源的。

WhatsApp 也在进行本地备份,通常每天两次在 sdcard/whatsapp 中。这些本地备份还包含身份密钥和消息存储数据库,实际上是加密的。加密密钥再次与您的 WhatsApp 个人资料一起存储在远程服务器上。这解释了为什么您可以将整个 WhatsApp 备份文件夹从一台设备移动到另一台设备。如果没有经过验证的电话号码,您将无法读取备份文件或使用身份密钥,但是任何有根设备都可以轻松访问原始的、未加密的数据库文件。

关于端对端加密协议的最后一句话:当您的至少一个朋友对他们的聊天进行 Google Drive 备份(聊天历史可检索)时,这似乎是无用的(不是针对普通黑客,但我认为针对美国的监视)。

从这一点来看,情况并没有好转,因为我们知道谷歌和 Facebook 和 WhatsApp 等其他公司根据 FISA 法案的要求提供文件。由于已经存在“后门”,因此无需攻击端到端通信。E2E 仅保护通信通道上的活跃对手,他们无权要求一方提供备份文件和另一方要求解密密钥。

攻击之窗

假设我们从资源有限的非政府或“普通”攻击者的角度来看情况,那么该设备就是明显的弱点。任何具有 root 权限的应用程序也可以访问数据库、复制密钥等。默认的 Android ROM 包含许多在系统用户下运行的应用程序,但供应商随 ROM (和更新)提供的应用程序也受到保护,不受用户干预,因此作为system运行。

恶意应用程序也并非没有风险。有了正确的权限,他们就可以完全控制 sdcard 存储,并且可以访问加密的备份。当验证短信在正确的时刻被截获(挂接短信接收呼叫)并复制电话号码时,应该可以激活自控WhatsApp实例并接收数据库解密密钥。如果对手控制了移动通信(政府经常这样做),攻击变得更加合理。

adb 攻击更糟糕,因为它不需要 root 权限。基本上,通过桥接接口安装旧版本的 WhatsApp 时,降级攻击是可能的。这种所谓的旧版 WhatsApp 可以被欺骗成完整的应用程序备份,从而生成 tar 存档。压缩包被拉到 adb 服务器端并解压缩。如果准备得当,它需要一根 USB 电缆和几秒钟的时间。

密钥由AES-GCM-256WhatsApp 服务器在注册时生成并发送给客户端。客户端将此密钥存储在/data/data/com.whatsapp/files/key. 每日聊天备份使用此密钥进行加密。密钥的256-bit IV256-bitId 存储在msgstore.db.crypt12其自身中。Id 用于标识加密备份的密钥。

当用户登录新设备时,它会从服务器检索密钥并解密备份。然后再次使用该密钥来加密每日聊天备份。WhatsApp 服务可能会在一段时间后为客户端轮换密钥。如果用户不想恢复备份,则由服务器生成新密钥。如果您删除密钥,则在您重新打开应用程序时会生成新密钥并将其发送给客户端。

这是客户端解密备份时whatsapp.log文件的过滤日志。每个日志的信息都在评论中。

# Look for local and cloud backups
[main] registername/check-for-local-and-remote-backups

# Query Google Drive for backups if your device is logged in with Google account
[WhatsApp Worker] gdrive-api-v2/auth-request asking GoogleAuthUtil for auth token: yourEmailId@gmail.com
[WhatsApp Worker] gdrive-api-v2/auth-request/received-auth-token
# Response from Google Drive: No backup exists
[WhatsApp Worker] gdrive-activity/one-time-setup/account-with-no-backup/yourEmailId@gmail.com

# Found local backup, get last backup file
[WhatsApp Worker] msgstore/lastbackupfile/file msgstore.db.crypt12 size=10485760
# Number of local backup files can be max 9 in your local storage, the older ones are deleted
[main] gdrive-activity/one-time-setup/num-of-local-backup-files/2
[main] gdrive-activity/one-time-setup no google drive backups found but local backup exists.

# Check if the backup belongs to your account by comparing
# last 2 digits in the footer with the last 2 digits of your phone number
# If it mismatches, raise exception, jid = jabber Id
[WhatsApp Worker] BackupFooter/has-jid-user-mismatch/expected-jid-user-ends-with: 20  actual-jid-user: YourPhoneNumberAlongWithCountryCode

[main] gdrive-activity/show-restore-for-local-backup
[main] gdrive-activity/show-msgstore-downloading-view
[main] gdrive-activity/msgstore-download/not performed since we are using local, success: true, now, restoring it.

# Get keys from WhatsApp server based on number of backups
# This key is same for multiple backups
# But sometimes when a user starts from fresh that is without restoring the backup,
# the key is changed, see in next logs
# WhatsApp server might also rotate keys for the client after some period of time
# The key is AES-GCM-256-bit key whose IV is stored in msgstore.db.crypt12
backupencryption/getkeys/size 2 (backups=2)

# Get cipher key from the key file with its Id
# When msgstore.db.crypt12 is generated,
# it stores Id of key in its header
# This Id is also stored in the key file
# to retrieve the key later for decryption
# 2 function calls because of 2 backup files
# Key can be same for both
[WriterThread] xmpp/writer/write/get-cipher-key
[WriterThread] xmpp/writer/write/get-cipher-key

# Only the latest backup is restored
[WhatsApp Worker] msgstore/restore/backupfiles msgstore.db.crypt12 (10485760)
[WhatsApp Worker] BackupFile/verifyIntegrity/CRYPT12
# Initial digest is md5 hash of an empty string
[WhatsApp Worker] BackupFile/getFileDigestWithoutFooter/initial digest = d41d8cd98f00b204e9800998ecf8427e
# Get file digest without footer, the last 20 bytes of backup is the footer
[WhatsApp Worker] msgstore-integrity-checker/verify-integrity/actual-digest/  b90a162a06ce60baf7dd89301d2149d6
[WhatsApp Worker] BackupFooter/verify-integrity/actual-digest/  b90a162a06ce60baf7dd89301d2149d6
Expected digest is the md5 hash stored in footer
[WhatsApp Worker] BackupFooter/verify-integrity/expected-digest/b90a162a06ce60baf7dd89301d2149d6
[WhatsApp Worker] BackupFooter/verify-integrity/digest-matches/success
[WhatsApp Worker] msgstore/restore/file-integrity-check/success
[WhatsApp Worker] msgstore/restore/key CRYPT12
[WhatsApp Worker] msgstore/restore/jid-mismatch/false
[main] gdrive-activity/msg-restore-progress/100%

# If md5 hash mismatches
[WhatsApp Worker] BackupFooter/verify-integrity/actual-digest/  f1c5e3afc42867f10f4e9107faf15cd3
[WhatsApp Worker] BackupFooter/verify-integrity/expected-digest/b90a162a06ce60baf7dd89301d2149d6
[WhatsApp Worker] BackupFooter/verify-integrity/failed expected-digest:b90a162a06ce60baf7dd89301d2149d6 actual-digest:f1c5e3afc42867f10f4e9107faf15cd3
[WhatsApp Worker] msgstore/restore/file-integrity-check/failed
[WhatsApp Worker] msgstore/restore/key CRYPT12
[WhatsApp Worker] msgstore/restore/error; exception=java.util.zip.ZipException: incorrect header check
[main] gdrive-activity/after-msgstore-verified/failed/unrestorable-local-backup

# If you start from fresh without restoring your backup, or
# If you delete the key file from /data/data/com.whatsapp/files/key
# Client requests new key from the server 
[WriterThread] xmpp/writer/write/create-cipher-key

# No internet connection
# If you delete the key file and try to make backup without going online
[WhatsApp Worker] localbackupmanager/sendCreateBackupKeyIfNeeded/started
[WhatsApp Worker] sendmethods/sendcreatecipherkey
[WhatsApp Worker] localbackupmanager/backup/waiting-for-the-key
[WhatsApp Worker] localbackupmanager/backup/backup-key-not-received
[WhatsApp Worker] backupkey/getinfo/does-not-exist

WhatsApp 服务无法访问保存在 Google 驱动器上的备份,因为它需要登录 Google 帐户才能请求 Oauth 令牌。如果 WhatsApp 真的想要,它可以简单地安装一个后门来magstore.dbcom.whatsapp/msgstore.db. 但是,执法部门可以命令 Google 获取备份并要求 WhatsApp 为他们解密。

将加密密钥存储在服务器上是一个糟糕的安全决策,因为它削弱了 E2EE 提供的设计安全性,并将攻击向量转移到了承诺的安全性上。Signal 使用 250,000 轮 SHA-512 随机生成的密码对备份进行加密,AES-CTR-256这是一种更好的方法。