📦 Monica WebDAV バックアップ形式仕様
概要
本仕様书は、Monica ローカル金庫が自動化された WebDAV バックアップやデータ転送を行う際に使用するアーカイブ構造、下位データフォーマット、および暗号化プロトコルを完全に定義します。このフレームワークにより、クロスプラットフォームでの高度な解析性能 と、一切の妥協のないプライバシーとセキュリティ が保証されます。
1. 総论 (Overview)
Monica の WebDAV バックアップメカニズムは、ユーザーのコアデータを標準の ZIP アーカイブ(暗号化されていない場合は .zip、高強度のバックアップ暗号化が有効な場合は .enc.zip)にバンドルします。
冗长で伝統的なバイナリデータベース(.db)の直接エクスポートとは異なり、このバックアップアーカイブは .json コアデータ、.csv サマリー、および 主に暗号化されたメディアリソース(Images) から構成される疎結合なアーキテクチャを採用しています。これにより、将来的なクロスプラットフォーム間(Android/ブラウザ/デスクトップ)でのデータ監査の簡素化と、極めて精密な復元ワークフローを実現しています。
2. バックアップアーカイブのディレクトリ構造
標準的なバックアップ ZIP アーカイブを解凍した際の完全なツリー構造は以下の通りです:
/ (ルートディレクトリ)
├── passwords/ # パスワード項目 (凝集度の高い個別JSON保存)
│ ├── password_1_1700000.json
│ └── password_2_1700001.json
├── notes/ # セキュアノートチャンク
│ └── note_1.json
├── cards/ # クレジットカードおよび身分証明書データ
│ └── bank_card_v1.json
├── authenticators/ # 2FA / TOTP 構成シード
│ └── totp_registry.json
├── images/ # 暗号化されたバイナリメディア添付ファイル群
│ ├── encrypted_photo_sha256.bin
│ └── secure_doc_avatar.bin
├── summary.csv # データのインデックスと簡易監査用サマリー
└── metadata.json # アーカイブのメタデータ、バージョン、およびハッシュ検証マニフェスト3. コア JSON スキーマ仕様
3.1 metadata.json (環境およびマニフェスト)
各バックアップパッケージのルートには、環境と完全性を検証するためのメタデータファイルが含まれます:
{
"version": "1.4.0",
"client": "Monica for Android",
"exportTimestamp": 1778956200000,
"cryptoProvider": "AES-256-GCM",
"manifest": {
"passwords/password_1_1700000.json": "sha256_hash_string_aaa",
"passwords/password_2_1700001.json": "sha256_hash_string_bbb"
}
}3.2 passwords/ 認証情報エンティティの構造例
各パスワードエンティティは、不必要な入れ子(ネスト)を避けるためにフラット化された高凝集な構造を維持します:
{
"id": 1700000,
"title": "GitHub 个人账户",
"username": "Base64_Encrypted_Username_Payload",
"password": "Base64_Encrypted_Password_Payload",
"websiteUrl": "[https://github.com](https://github.com)",
"categoryId": 2,
"isFavorite": true,
"ssoRefEntryId": -1,
"totpSecret": "Base64_Encrypted_TOTP_Secret",
"customFields": [
{
"fieldName": "Recovery_Key",
"fieldValue": "Base64_Encrypted_Value",
"isProtected": true
}
],
"lastModified": 1778956000000
}4. 暗号化構造とペイロード管理
高強度暗号化が有効である場合、データの漏洩を防ぐために、圧縮ストリーム全体に対して落盤前(永続化前)に AES-256-GCM による全盤処理が課されます。
4.1 ファイルヘッダーの構造設計
暗号化されたバイナリファイル(.enc.zip)の最前方(ヘッダー)には、固有のマジックバイトシーケンスが厳格に結合されています:
| オフセット範囲 (Byte) | 割り当てデータ定義 | 役割・説明 |
|---|---|---|
0x00 - 0x0C | MONICA_ENC_V1 (13字) | フォーマット世代のバージョン識別用マジックナンバー |
0x0D - 0x1C | Salt (16字节) | PBKDF2 鍵派生用の高エントロピーな動的ソルト |
0x1D - 0x28 | IV (12字节) | AES-256-GCM 暗号化用の初期化ベクトル |
0x29 - 末尾 | Ciphertext | 後続の完全に暗号化された ZIP バイナリストリームペイロード |
4.2 ストリーム暗号化の擬似ロジック
val derivedKey = PBKDF2.derive(backupPassword, salt, iterations = 100000)
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.ENCRYPT_MODE, SecretKeySpec(derivedKey, "AES"), GCMParameterSpec(128, iv))
val encryptedData = cipher.doFinal(rawZipBytes)
outputStream.write(MAGIC_BYTES)
outputStream.write(salt)
outputStream.write(iv)
outputStream.write(encryptedData)5. クロスデバイス復元および衝突緩和ロジック
データの復元(レストア)フェーズにおいて、クライアントのランタイムは以下のシーケンシャルなパイプラインを厳格に実行します:
5.1 ライフサイクル実行ステップ
- 復号と検証:
.enc.zipをデコード ➔ ヘッダーブロックの完全性を検証 ➔ マスターパスワード派生キーを介してストリームを復号 ➔ メモリ内の隔離されたサンドボックス(Temp空間)にファイルを展開。 - ID 衝突の解決:
- 抽出された JSON 項目の主キー
idが、現在デバイス上でアクティブなデータベース内に既に存在していることが判明した場合、エンジンは直接的な上書き(データ汚染)を拒否します。 - 代替ルート(フォールバック)をトリガー:インポートされるレコードに対して、現在のタイムスタンプベースの新しい物理的なユニーク
Long IDを再割り当てし、データベースに安全に新規挿入(Insert)します。
- 関係グラフの再構築(ID マッピング修復):
- ランタイムルーチンは、一時的な
古いID ➔ 新しいIDの対応関係マップ(マッピング表)をメモリ上にコンパイルします。 ssoRefEntryIdパラメータ、ペア化されたアカウントインジケータ、および関連する TOTP バインド関係を自動的にスキャン・パッチ(修復)し、データ構造の整合性を壊すことなく関係グラフの結合関係を100%維持します。
- メディア資産の再配置:
images/ディレクトリツリー内のすべてのバイナリレコードを処理します。- スナップショットやドキュメントの添付ファイルを、ホストアプリの隔離されたローカルファイルシステム空間(
context.filesDir)へ安全に移行し、アクティブなノートデータベース内の対応する内部パスバインドを書き換えます。
6. 例外処理(サーキットブレーカー制度)
- 整合性の破壊:解凍時に
metadata.json内のマニフェストハッシュと実際の JSON ハッシュが一致しない場合、インポートタスクは即座に中断され、ローカルデータベースは自動的にTransaction Rollback(トランザクション・ロールバック)を実行して整合性を保護します。 - 暗号化エラー:パスワードが間違っている、または AEAD 認証タグの検証に失敗した場合、メモリ内の鍵バッファは直ちにクリア(ゼロクリア)され、不完全な明文データがディスクに書き込まれるのを防ぎます。
