ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Ente 端到端加密架构解析:密钥体系、文件加密、分享与恢复的完整设计

Ente 端到端加密架构解析:密钥体系、文件加密、分享与恢复的完整设计 Ente 端到端加密架构解析密钥体系、文件加密、分享与恢复的完整设计【免费下载链接】ente End-to-end encrypted cloud for everything.项目地址: https://gitcode.com/GitHub_Trending/en/enteEnte 是一个一切皆端到端加密End-to-end encrypted cloud for everything的开源云服务覆盖照片备份Photos、认证器Auth/Ensu与文件保险库Locker等场景。本文以 architecture/README.md 为核心骨架结合仓库内 CLI、移动端与服务端的真实实现系统讲解 Ente 的加密密钥分层体系、数据上传/下载加解密流程、加密分享、密钥恢复、认证机制以及底层密码学原语libsodium的落地细节。读完本文你将能完整理解 Ente 从注册、上传、分享到密码找回的整条端到端加密链路以及这些设计在源码中对应的实现位置。端到端加密的基本原理Ente 的设计前提只有一句话你的数据在离开设备之前就已经用你的密钥完成了加密。也就是说服务器上存储的永远是密文服务器无法读取你的照片、文件或认证令牌。加密所用的keys密钥由客户端生成在离开设备之前以密文形式保存源码已经过第三方密码学审计以验证密钥只归你所有由于只有你能持有并解出这些密钥因此只有你能够访问自己的数据。这一客户端生成密钥 服务端只存密文 密钥永不裸奔的模型构成了后面所有章节的基础。Key Encryption密钥的加密注册与登录基础概念Master Key主密钥注册时由你的客户端生成一个masterKey。它永远不会以未加密的形式离开设备是整个加密体系的最顶层密钥。Key Encryption KeyKEK密钥加密密钥当你选择密码后客户端会从密码中派生出一个keyEncryptionKey用于加密masterKey。它同样永远不会离开设备只存在于内存会话中。注册流程主设备在主设备上注册时客户端生成masterKey从你设定的密码派生keyEncryptionKey用keyEncryptionKey加密masterKey得到encryptedMasterKey将encryptedMasterKey上传到服务器存储。登录流程次设备在新设备上登录时客户端请求服务器发送一次性验证码OTP到你的邮箱邮箱验证通过后服务器把主设备上传的encryptedMasterKey返回给客户端客户端提示你输入密码并在本地派生keyEncryptionKey用keyEncryptionKey解密encryptedMasterKey还原出masterKey。如果解密失败说明派生的keyEncryptionKey不正确即密码输入有误客户端会明确向你提示这一信息——密码错误是在本地被发现的服务器永远不会知道你的密码对错。隐私保证只有你知道密码 → 只有你能派生keyEncryptionKey只有你能派生keyEncryptionKey→ 只有你能访问masterKey。Data Encryption数据的加密上传与下载基础概念Collection Key集合密钥你在 Ente 中的每条数据都属于一个collection。collection可以是文件夹如Camera、Screenshots或相册如Awkward Reunion在 Auth认证器场景下客户端会自动创建一个默认根集合。每个collection持有一个collectionKey同样永远不会以未加密形式离开设备。File Key文件密钥你的每一份数据都对应一个fileKey也永远不会未加密地离开设备。上传流程每个文件及其关联元数据都用随机生成的fileKey加密每个fileKey再用该文件所属collection的collectionKey加密如果该集合尚不存在则新建一个并生成随机的collectionKey所有集合元数据名称、文件夹路径等也用这个collectionKey加密每个collectionKey再用你的masterKey加密上述所有密文统一推送到服务器存储。下载流程从服务器拉取上述所有密文先用masterKey解密每个文件的collectionKey再用collectionKey解密对应的fileKey最后用fileKey解密文件及其元数据。隐私保证只有你有masterKey→ 只有你能解密collectionKey只有你有collectionKey→ 只有你能解密fileKey只有你有fileKey→ 只有你能解密文件及其元数据。源码印证流式文件加解密CLI 客户端在 cli/internal/crypto/crypto_native.go 中实现了DecryptFile它以 4 MiBdecryptionBufferSize定义于 cli/internal/crypto/crypto.go为缓冲分块拉取密文调用基于 XChaCha20-Poly1305 的流式解密器逐步还原明文直至遇到TagFinal标签或 EOF。对应的流式加密器实现位于 cli/internal/crypto/stream.go其中TagFinal TagPush | TagRekey并严格校验每个分块的 Poly1305 MAC——任何篡改都会导致cryptoFailure错误。Sharing加密分享基础概念Public Key公钥注册时应用为你生成一对密钥中的公钥。它是公开的以明文形式存储在服务器上。Verification ID验证标识公钥的人类可读表示可在客户端内用于核对接收方身份。生成方式是取公钥的 SHA-256 值再转换成对应的 BIP39 助记词短语。Private Key私钥与公钥配套生成的私钥永远不会未加密地离开设备。私钥由你的masterKey加密后得到encryptedPrivateKey存储在服务器上。分享流程分享与数据加密的流程类似唯一区别在于被分享集合的collectionKey会用接收方的公钥加密。发送方文件及其元数据已用随机fileKey加密每个fileKey已用所属集合的collectionKey加密现在将collectionKey用接收方公钥加密将以上密文推送到服务器。接收方从服务器拉取密文先用自己的私钥解密collectionKey再用collectionKey解密各文件的fileKey最后用fileKey解密文件及其元数据。隐私保证只有接收方拥有自己的masterKey→ 只有接收方能解密encryptedPrivateKey取得私钥只有接收方拥有私钥 → 只有接收方能解密发送方加密的collectionKey只有接收方拥有collectionKey→ 只有接收方能解密该相册/文件夹中文件的fileKey只有接收方拥有这些fileKey→ 只有接收方能解密文件及其元数据。发送方可以在应用的分享界面查看接收方的 Verification ID并与接收方设备上显示的 Verification ID 比对。两端标识一致即可确认双方之间的端到端加密是安全的防止中间人替换公钥。Key Recovery密钥恢复忘记密码基础概念Recovery Key恢复密钥注册时应用为你生成一个recoveryKey永远不会未加密地离开设备。存储你的recoveryKey和masterKey会互相加密masterKey用recoveryKey加密recoveryKey用masterKey加密然后一并存储在服务器上。访问在新设备登录时服务器会下发加密后的recoveryKey客户端用masterKey解密并在你主动请求时展示给你例如用于抄写备份。恢复流程忘记密码时邮箱验证通过后客户端提示你输入recoveryKey客户端拉取服务器上此前存储的、用recoveryKey加密的masterKey并用输入的recoveryKey解密解密成功即证明recoveryKey输入正确客户端获得masterKey客户端提示你设置新密码派生新的keyEncryptionKey重新加密masterKey并上传服务器——与注册时的 Key Encryption 流程完全一致。隐私保证只有你有masterKey→ 只有你能访问recoveryKey只有你能访问recoveryKey→ 只有你能重置密码。源码印证KeyAttributes 的存储模型服务端在 server/ente/user.go 中定义了KeyAttributes结构完整承载了上述密钥体系的持久化字段KEKSalt/KEKHash密码派生 KEK 时使用的盐与哈希EncryptedKeyKeyDecryptionNonce被 KEK 加密的masterKey及其 noncePublicKey公钥明文EncryptedSecretKeySecretKeyDecryptionNonce被masterKey加密的私钥及其 nonceMemLimit/OpsLimit密码派生算法Argon2的内存与计算开销参数MasterKeyEncryptedWithRecoveryKeyMasterKeyDecryptionNonce用恢复密钥加密的masterKeyRecoveryKeyEncryptedWithMasterKeyRecoveryKeyDecryptionNonce用masterKey加密的恢复密钥。其中互相加密正是MasterKeyEncryptedWithRecoveryKey与RecoveryKeyEncryptedWithMasterKey两个字段所体现的设计其读写与验证逻辑位于 server/pkg/controller/user/user.go 和 server/pkg/repo/user.go。Authentication认证机制基础概念One Time Token一次性令牌OTT当你验证某个邮箱的所有权时服务器生成一个oneTimeToken出示该令牌即证明你能访问该邮箱。令牌有效期很短且只能使用一次。Authentication Token认证令牌authToken当你成功向服务器证明邮箱所有权未来还会支持其他配置的验证途径后服务器生成authToken此后用于调用 Ente 的私有 API。Encrypted Authentication Token加密的认证令牌生成的authToken会用你的公钥加密后返回给客户端得到encryptedAuthToken只有你的私钥能解密。完整登录流程输入邮箱地址服务器向该邮箱发送oneTimeToken正确出示令牌后服务器生成authToken并将encryptedAuthToken连同其他加密密钥一并返回客户端提示输入密码据此派生masterKey同次设备登录流程用masterKey解密其余密钥包括privateKey用privateKey解密服务器用你的公钥加密的encryptedAuthToken此后使用解密出的authToken认证所有 API 调用。安全保证只有同时做到验证邮箱所有权且知道密码你才能获得可用于认证服务器 API 的authToken——即认证是邮箱所有权 密码知识的双重结果。源码印证登录 API 端点CLI 客户端在 cli/internal/api/login.go 中封装了这条链路对应的全部 HTTP 端点POST /users/ott发送登录一次性验证码SendLoginOTP第 86-110 行POST /users/verify-email校验 OTP 并换取授权响应VerifyEmail第 112-137 行POST /users/two-factor/verify若启用了 2FA还需校验 TOTP 码VerifyTotp第 139-164 行可选地GET /users/srp/attributes、POST /users/srp/create-session、POST /users/srp/verify-session用于基于 SRP 的无密码泄露登录第 9-84 行GET /users/two-factor/passkeys/get-token用于 Passkey 登录令牌第 166-183 行。Token EncryptionAuth 应用的令牌加密Ente Auth认证器应用遵循几乎相同的架构只是把文件换成了认证令牌及其元数据。基础概念Token Key你的每个认证令牌都用tokenKey加密tokenKey永远不会未加密地离开设备。Authenticator KeyauthKey每个tokenKey再用authKey加密authKey也永远不会未加密地离开设备。上传流程每个令牌及其元数据用随机生成的tokenKey加密每个tokenKey用你的authKey加密如果账户还没有authKey则随机生成一个并用masterKey加密以上密文全部推送到服务器。下载流程从服务器拉取密文先用masterKey解密authKey再用authKey解密每个令牌的tokenKey最后用tokenKey解密令牌及其元数据。隐私保证只有你有masterKey→ 只有你能解密authKey只有你有authKey→ 只有你能解密tokenKey只有你有tokenKey→ 只有你能解密令牌及其元数据。Implementation Details底层密码学实现Ente 的全部加密能力建立在密码学库libsodium之上仓库中的各个客户端Dart、Go、Rust、Swift/Kotlin都围绕其高层 API 实现。下表汇总了每种用途对应的原语用途libsodium API内部算法生成所有随机密钥crypto_secretbox_keygen—生成公私钥对crypto_box_keypairX25519从密码派生密钥crypto_pwhashArgon2 v1.3加密密钥与密钥小数据crypto_secretbox_easyXSalsa20 Poly1305 MAC分块加密文件/令牌数据crypto_secretstream_*XChaCha20 Poly1305 MAC非对称加密分享、令牌下发crypto_box_sealX25519 XSalsa20 Poly1305 MAC生成盐与 noncerandombytes_buf加密安全随机数密钥生成masterKey、recoveryKey、collectionKey、fileKeyAuth 中的authKey、tokenKey均为 256 位密钥由crypto_secretbox_keygen生成。密钥对生成publicKey/privateKey由crypto_box_keypair生成底层为 X25519 曲线。密钥派生keyEncryptionKey由crypto_pwhash从密码派生使用crypto_pwhash_OPSLIMIT_SENSITIVE与crypto_pwhash_MEMLIMIT_SENSITIVE作为计算/内存开销上限。如果设备内存不足导致派生失败客户端会逐步将计算开销加倍、内存开销减半继续尝试一旦内存上限被降到低于服务器接受的下限128 MiB该设备将不允许注册。对称加密密钥层masterKey、recoveryKey、privateKey、collectionKey、fileKeyAuth 中的authKey、tokenKey用crypto_secretbox_easy加密内部为 XSalsa20 流密码 Poly1305 MAC。对称加密数据层文件数据Auth 中的令牌数据用crypto_secretstream_*分块加密内部为 XChaCha20 流密码 Poly1305 MAC。非对称加密分享时用crypto_box_seal以接收方公钥加密collectionKey下发的authToken也用同一 API 以用户公钥加密。盐与 nonce每次哈希/加密都通过randombytes_buf生成新的盐或 nonce。Verification ID公钥的 SHA-256 值转换为对应的 BIP39 助记词短语。源码印证Go CLI 中的对应实现仓库内 cli/internal/crypto/crypto.go 的DeriveArgonKey直接调用argon2.IDKey(password, saltBytes, opsLimit, memLimit/1024, 1, 32)——这正是crypto_pwhash的 Argon2 实现输出 32 字节256 位密钥。同文件中的deriveSubKey还基于 BLAKE2b 派生登录子密钥体现同一masterKey用于多种上下文派生的设计。cli/internal/crypto/crypto_native.go 则印证了对称与非对称原语SecretBoxOpen严格要求24 字节 nonce、32 字节密钥并调用 Go 标准库的nacl/secretbox完成 XSalsa20-Poly1305 解密SealedBoxOpen调用box.OpenAnonymousX25519 匿名密封盒对应crypto_box_sealdecryptChaCha20poly1305V2接受TagFinal与TagMessage两种收尾标签以兼容 Ente Auth 历史数据的差异见 cli/internal/crypto/crypto_native.go。源码印证服务端的 KDF 强度校验服务端在 server/ente/user.go 对客户端上传的密钥属性做双重校验MemLimit * OpsLimit必须等于预期的 KDF 强度ExpectedKDFStrength且MemLimit不得低于128 MiB。这从服务器侧保证了所有客户端的密码派生强度一致也呼应了文档中内存下限 128 MiB低于该值不允许注册的说明。总结层层加密的密钥体系Ente 的端到端加密本质是一个四层密钥嵌套模型密码 → keyEncryptionKey(KEK) → masterKey → collectionKey/authKey → fileKey/tokenKey → 数据密钥KEK/masterKey永不离开设备只有密文形态的encryptedMasterKey才会同步到服务器数据加密采用每文件随机密钥 每集合密钥 主密钥的分层结构既保证了单文件密钥泄露不波及其他文件又让分享只需在collectionKey层做一次换锁改用接收方公钥加密即可忘记密码时依靠recoveryKey 与 masterKey 互相加密的设计安全重置密码认证则要求邮箱所有权 密码知识双重证明且下发的authToken也要用你的公钥加密形成完整闭环。从 架构文档 到 CLI 加密实现、服务端密钥存储 与 登录 API这一套设计在仓库中处处可查、可验证也正是 Ente 宣称只有你能访问你的数据的技术根基。【免费下载链接】ente End-to-end encrypted cloud for everything.项目地址: https://gitcode.com/GitHub_Trending/en/ente创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表