官方同步端对端加密功能的验证方法

在我们的关于页面中,我们阐述了自 Obsidian 成立以来始终秉持的原则。其中,隐私权一直是我们最重视的,我们将不遗余力地保护这一原则:

我们坚信,你的思想和创新理念是你的私有财产,应享有充分的隐私权。因此,你的数据会被保存在你的设备上,我们无权访问。当你使用我们的在线服务时,你的数据将通过端到端加密进行最大程度的安全保护。

使用 Obsidian Sync 时,你的数据将进行端对端的加密。然而,你如何确定这一点呢?

在本指南中,我们提供了逐步指南,帮助你在通过我们的 Sync 服务器发送和接收数据时,无需信任即可验证你的数据是否实现了端到端加密。

Obsidian Sync 如何运行

让我们回顾一下 Obsidian Sync 的加密过程:

  1. 你可以自行设定一个库密码,或者由我们的托管服务器为你生成一个。这个密码与你的账户密码不同,仅用于建立一个远程库。

  2. Obsidian 应用会为每个库生成一个独一无二的salt。Salt 是一种随机数据,用于在进行哈希(HASH)运算前与你的密码混合,以保护你的密码。

  3. 你的加密密钥是通过一种名为 scrypt 的算法从你的密码+salt 中派生出来的。

  4. 这个加密密钥将用于利用 Galois/Counter ModeAES-256 的数据进行加密/解密。

在接下来的部分,你将学习如何获取你的库的 salt,以及如何测试你的数据的加密程度。

获取你的库的 salt

首先,按照以下步骤获取用于派生你的加密密钥的 salt:

  1. 确保 Obsidian Sync 已经启动。

  2. 使用快捷键 Cmd+Opt+I(在 macOS 上)或 Ctrl+Shift+I(在 Windows 上)在 Obsidian 应用中打开开发者工具。

  3. 转到控制台,然后运行以下代码,只需复制/粘贴它,然后按下 Return 键:


let data = await new Promise(r => app.account.getVaults(r));

let vaults = [].concat(data.shared, data.vaults);

let vault = vaults.find(v => v.id === app.internalPlugins.getEnabledPluginById('sync').vaultId);

console.log(`The salt of your vault ${vault.name} is: "${vault.salt}"`);

你应该看到一条包含你的盐(salt)的信息:


你的 vault Notes 的盐是:"8II2%?YeNpddlbd@4Z)c"

数据解密

接下来,我们将选取一个同步事件作为例子进行解密。这需要使用开发者工具的“网络”标签页。所有的同步事件都在这里记录下来,这样你就能看到 Obsidian 应用发送和接收的数据,并验证这些数据是否使用了你的加密密钥。

  1. 转到开发者工具的“网络”标签页,然后使用 “WS” 类型进行过滤(这代表 WebSocket)。

  2. 找到 Obsidian Sync 的 WebSocket 连接。它的名称应类似于 sync-xx.obsidian.md——你可能需要刷新 Obsidian 才能看到它。

  3. 在 WebSocket 数据流中,转到“消息”标签页。你将在那里看到上传和下载的二进制消息。如果你还没看到它们,可以通过修改你库中的任何已同步的笔记来轻松触发一个同步事件。

  4. 在这些消息中选取一个,右键点击,然后选择 复制消息 > 复制为Base64

  5. 使用下面的代码,输入你的密码、你的盐,以及 Base 64 编码的二进制数据,在控制台中运行解密程序(或者你也可以在 NodeJS 提示符或脚本中运行它)。


// 使用 NodeJS 的标准 crypto 包

let crypto = require('crypto');

// 输入你的密码,盐,以及 base64 格式的二进制数据

let password = 'E@QAXVBo44PQtzS6EAyU';

let salt = '8II2%?YeNpddlbd@4Z)c';

let data = Buffer.from('ApLmsQVGwGHmjb7jM4G2ZXnl2+Wi8CJMZSbgCTvcBHendXw01iNw3oWQ8Y8gW1tS7f/OMly1n4KoNhjy', 'base64');

// 从你的密码和盐中派生出加密/解密密钥

let key = crypto.scryptSync(Buffer.from(password.normalize('NFKC'), 'utf8'), Buffer.from(salt.normalize('NFKC'), 'utf8'),

32, {N: 32768, r: 8, p: 1, maxmem: 128 * 32768 * 8 * 2});

// 将数据块分成 12 字节的 IV,加密数据,以及 16 字节的认证标签。

let iv = data.subarray(0, 12);

let encryptedData = data.subarray(12, data.length - 16);

let authTag = data.subarray(data.length - 16);

// 解密数据

let decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);

decipher.setAuthTag(authTag);

let decrypted = Buffer.concat([decipher.update(encryptedData), decipher.final()]);

// 将其打印成字符串

console.log(decrypted.toString('utf8'));

返回的数据应是经过 Obsidian Sync 服务器发送或接收的文件的某个版本。就是这么简单!如果能正确解密,那就证明你的加密密钥是有效的。

原文见: How to verify Obsidian Sync’s end-to-end encryption - Obsidian
翻译:Bon

5 个赞