
Joplin E2EE 同步快照解析一個加密 Resource 同步項的字段、密文格式與測試用途【免費下載鏈接】joplinJoplin - the privacy-focused note taking app with sync capabilities for Windows, macOS, Linux, Android and iOS.項目地址: https://gitcode.com/GitHub_Trending/jo/joplin在 Joplin 的端到端加密E2EE同步體系中同步目標sync target上的每個對象都會以「同步項」的形式落盤本文以倉庫中一個真實的測試快照 bda6d120223140afbe7f03ef1d876400.md 為樣本逐字段拆解一個啟用端到端加密后的 Resource資源同步項它是如何表示的、encryption_cipher_text里的密文由哪些參數(shù)構(gòu)成、以及這類快照文件在 app-cli 的同步測試流程中扮演什么角色。讀完后你可以獨立解讀 Joplin E2EE 同步目錄中的任意.md同步項文件并復(fù)現(xiàn)快照的生成與部署流程??煺漳夸浀恼w結(jié)構(gòu)這個樣本文件位于同步目標快照目錄的版本 2 下完整路徑為 packages/app-cli/tests/support/syncTargetSnapshots/2/e2ee/bda6d120223140afbe7f03ef1d876400.md。同目錄下還存在一個平行的normal未加密目錄兩者結(jié)構(gòu)相同均包含一組以對象 ID 命名的.md文件、一個info.json和一個locks/目錄e2ee 目錄20 個加密同步項 info.json內(nèi)容為{version:2}聲明該快照對應(yīng)的同步協(xié)議版本normal 目錄對應(yīng)的未加密快照便于對照加密與否時的字段差異。這些快照并非手工維護的示例而是由測試工具自動生成、再回放到其它測試中。packages/lib/testing/syncTargetUtils.ts 中的deploySyncTargetSnapshot會把syncTargetSnapshots/{版本}/{normal|e2ee}整個目錄拷貝到測試用的同步目錄syncDir模擬一個「遠端服務(wù)器已經(jīng)存有這些對象」的狀態(tài)其配套函數(shù)mainL119-L147則反向工作創(chuàng)建測試數(shù)據(jù)、按需開啟加密setEncryptionEnabled(true) 加載主密鑰、執(zhí)行一次同步再把同步目錄內(nèi)容固化回快照目錄。官方服務(wù)規(guī)范 readme/dev/spec/server_items.md 也明確引用了該目錄作為「序列化 Joplin 同步項」的示例來源供PUT /api/items接口的實現(xiàn)方參考。字段逐行解讀一個加密 Resource 同步項樣本文件全文只有 14 行是典型的「Joplin 同步項序列化格式」——以字段名: 值逐行排列。對照未加密的normal快照即可看出加密模式下敏感字段的值被清空由密文字段替代。逐字段說明如下字段樣本值含義idbda6d120223140afbe7f03ef1d876400同步項的全局唯一 ID32 位十六進制文件名即取自它mime空資源的 MIME 類型。E2EE 模式下該字段被加密遠端可見部分為空filename空資源的原始文件名同上密文加密后不對外暴露created_time/updated_time后者為2020-07-25T10:55:20.778Z服務(wù)端時間戳updated_time用于同步時判斷沖突與版本先后user_created_time/user_updated_time空客戶端本地記錄的用戶時間戳file_extension空文件擴展名同樣是可被加密的字段encryption_cipher_textJED0100002...見下文上述敏感字段的密文這是整個文件的技術(shù)核心encryption_applied1標記「本對象已應(yīng)用端到端加密」同步器據(jù)此決定解密路徑encryption_blob_encrypted空用于大體積加密 blob 的分塊場景本樣本未使用size空資源字節(jié)大小加密后對外隱藏is_shared空是否共享資源的標志位type_4對象類型。對照 packages/lib/BaseModel.ts 中ItemType枚舉的Resource 4可確認這是一個「筆記資源」類型對象如筆記中嵌入的圖片或附件而非 Note 或 Foldertype_字段本身不參與加密——同步協(xié)議需要它來路由處理邏輯。packages/lib/Synchronizer.ts 中同步器正是通過content.type_ BaseModel.TYPE_RESOURCE判斷是否處于「創(chuàng)建或更新資源」的分支進而走資源的特殊處理如 blob 傳輸這解釋了為什么即使mime、filename、size全部加密為空同步器依然能正確識別并處理這個對象。encryption_cipher_textJED 前綴與 libsodium 密封盒參數(shù)密文字段的完整取值形如JED0100002205a1a0987e82cc400c90582492f814c23c000308{iv:zyEI38ZCb2UGn3cy0Ejjjg,v:1,iter:101,ks:128,ts:64,mode:ccm,adata:,cipher:aes,salt:Gyo7bQeqz2w,ct:vqxf3Ul0liOt86X6uiY3/...}可以把它拆成「前綴 序列化 JSON 密文」兩部分JED前綴Joplin 對序列化加密對象Encrypted object Data的標識。后續(xù)字符包含版本號01與加密對象自身的 ID000002205a1a0987e82cc400c90582492f814c23c000308中可辨識出與a1a0987e82cc400c90582492f814c23c相關(guān)的對象標識用于區(qū)分未加密的普通數(shù)據(jù)與加密數(shù)據(jù)。libsodium 密封盒secretbox序列化結(jié)構(gòu){iv:...,v:1,iter:101,ks:128,ts:64,mode:ccm,adata:,cipher:aes,salt:...,ct:...}是libsodium-wrappers的crypto_secretbox_easy序列化輸出的標準字段集v: 1序列化格式版本iter: 101、ks: 128、ts: 64KDF 迭代次數(shù) 101 次、密鑰長度 128 位、標簽長度 64 位mode: ccm、cipher: aes底層為 AES-CCM 認證加密iv/salt隨機初始向量與鹽每次加密都重新生成保證同一明文產(chǎn)生不同密文adata附加認證數(shù)據(jù)此處為空ctBase64 編碼的實際密文內(nèi)部封裝的是被加密的原始對象 JSON含mime、filename、size等明文值。結(jié)合 packages/lib/testing/syncTargetUtils.ts 中 e2ee 分支的邏輯——先setEncryptionEnabled(true)再loadEncryptionMasterKey()后才執(zhí)行同步——可以確認解密這一層密文需要客戶端主密鑰派生出的密鑰只有持有主密鑰或 Joplin Cloud 中托管的密鑰材料的客戶端才能還原出mime: image/jpeg之類的明文元數(shù)據(jù)。這正是 E2EE 的語義服務(wù)端本例中是快照目錄模擬的遠端只保存密文與encryption_applied: 1標志元數(shù)據(jù)本身不出現(xiàn)在任何明文字段中。encryption_blob_encrypted在本樣本中為空從源碼結(jié)構(gòu)看它是為資源文件體blob分塊加密傳輸預(yù)留的字段元數(shù)據(jù)小、直接內(nèi)聯(lián)進encryption_cipher_text而 blob 體積大會走獨立的加密通道并記錄在此處??煺杖绾悟?qū)動同步回歸測試理解了這個文件的來龍去脈就能明白 Joplin 如何用「快照回放」做跨版本、跨實現(xiàn)的同步回歸生成main(e2ee)以客戶端 1 初始化數(shù)據(jù)庫與同步器按 testData 描述的結(jié)構(gòu)folder1 → subFolder1/subFolder2(note1resource, tag1) …共 5 個文件夾、5 篇筆記、2 個資源、2 個標簽創(chuàng)建對象開啟 E2EE 并加載主密鑰同步一次再把同步目錄內(nèi)容寫回syncTargetSnapshots/{syncVersion}/e2ee/L138-L146。本樣本中info.json的version: 2即同步協(xié)議版本對應(yīng)目錄2/?;胤牌渌鼫y試如協(xié)議升級/遷移相關(guān)測試 synchronizer_MigrationHandler.test.ts調(diào)用deploySyncTargetSnapshot(e2ee, 2)將快照拷入syncDir隨后讓同步器與之同步驗證客戶端能正確解密元數(shù)據(jù)、識別type_ 4的資源對象、完成 blob 下載等全鏈路行為。校驗checkTestDataL75-L111會逐條斷言每篇筆記可按標題加載、父文件夾存在、筆記中的資源圖片 URL 能解析出可加載的 Resource 對象、標簽與筆記的關(guān)聯(lián)完整——這正對應(yīng)快照中note1/note5攜帶resource: true的兩類 Resource 同步項本樣本即其中之一。小結(jié)從一份快照文件看 Joplin E2EE 同步項格式一個同步項 id 元數(shù)據(jù)字段 type_ 加密時encryption_cipher_text與encryption_applied本樣本是一個type_ 4的 Resource 對象元數(shù)據(jù)mime、filename、size、file_extension全部被 AES-CCM 密封盒密文替代僅id、時間戳與類型號保持明文以支撐同步協(xié)議運行。密文為 libsodiumcrypto_secretbox_easy序列化格式v/iter/ks/ts/mode/cipher/iv/salt/ct由JED前綴標識加密序列化對象與 BaseModel.ts 中的類型枚舉、Synchronizer.ts 中的資源分支處理相互印證。快照目錄是「生成—固化—回放」的閉環(huán)syncTargetUtils.ts 負責雙向流轉(zhuǎn)normal與e2ee兩套目錄支持明文/加密路徑的對照回歸server_items.md 則把它作為服務(wù)端PUT /api/items接口的序列化示例來源。需要說明的前提syncTargetSnapshots是版本 2 同步協(xié)議的測試數(shù)據(jù)字段格式隨協(xié)議版本演進可能變化本文解析以該倉庫當前快照內(nèi)容及其配套測試工具為準?!久赓M下載鏈接】joplinJoplin - the privacy-focused note taking app with sync capabilities for Windows, macOS, Linux, Android and iOS.項目地址: https://gitcode.com/GitHub_Trending/jo/joplin創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考