技術文書

システムアーキテクチャ

NuDefndrのプライバシー第一のアーキテクチャの詳細。 実装。監査可能なコード。

システム概要

オンデバイス処理パイプライン

┌──────────────────────────────────────────────────────────────────┐ │ NUDEFNDR 分析フロー │ └──────────────────────────────────────────────────────────────────┘ ユーザーの写真ライブラリ (iOS Photos.framework) │ ├─> [PhotoLibraryService: PHAssetを取得] │ ├─ インクリメンタルスキャン (タイムスタンプベースのスキップ) │ └─ 対象: 過去24時間 / 7日 / 30日 / 90日 / 全て │ ▼ バッチ処理キュー │ ├─> [デバイス対応の並行処理] │ ├─ A17+ デバイス: 6つの並行分析 │ ├─ A15/A16: 3つの並行分析 │ └─ 旧機種: 順次処理 │ ▼ APPLE ML フレームワーク (iOS 18+) │ ├─> [SensitiveContentAnalysis.framework] │ ├─ オンデバイスのNeural Engine処理 │ ├─ バイナリ分類 (センシティブ/安全) │ └─ ネットワーク活動ゼロ (検証済み) │ ▼ 結果パイプライン │ ├─> [一時キャッシュ - RAMのみ] │ ├─ 結果は永続化されない │ └─ アプリ終了時にクリア │ ▼ ユーザーレビュー │ └─> [ユーザーアクション: 移動/コピー/無視] ├─ ボールトに移動 →暗号化 + 写真から削除 ├─ ボールトにコピー →暗号化 + 写真に保持 └─ 安全とマーク → 将来のスキャンから除外 ┌──────────────────────────────────────────────────────────────────┐ │ プライバシー保証 │ └──────────────────────────────────────────────────────────────────┘ ✓ 分析中のネットワークリクエストゼロ ✓ クラウドアップロードなし (すべての処理がローカル) ✓ 結果はログ記録または永続化されない ✓ 分析後にメモリがクリアされる ✓ Appleのプライバシー第一のMLフレームワーク

NEURAL ENGINE

A12+チップでのハードウェアアクセラレーションML処理。分析中のCPUオーバーヘッドはゼロ。

サンドボックス化

iOS App Sandboxがデータ流出を防ぎます。分析中にネットワークリクエストがブロックされます。

インクリメンタル

スマートタイムスタンプスキップは、繰り返しスキャンで新規/変更された写真のみを分析します。

ソースコード

インクリメンタルスキャンエンジン

> /Services/ScanManager.swift スマートタイムスタンプスキップ (v2.0+)
/// タイムスタンプベースのスキップロジックによるインクリメンタルスキャン
/// 繰り返しスキャンで5〜15倍のパフォーマンス向上を実現
func performIncrementalScan(range: ScanRangeOption) async throws {
    guard let lastScanDate = getLastSuccessfulScanDate() else {
        // 初回スキャン - すべてを分析
        return try await fullScan(range: range)
    }
    
    var skippedCount = 0
    var analyzedCount = 0
    
    for asset in photoAssets {
        // スキップロジック: 写真は最終スキャン以降変更されていない
        if let modDate = asset.modificationDate,
           modDate < lastScanDate {
            skippedCount += 1
            continue // この写真をスキップ (分析済み)
        }
        
        // 写真を分析 (最終スキャン以降に新規または変更されたもの)
        let result = try await analyzer.analyze(asset)
        analyzedCount += 1
        
        if result.isSensitive {
            await notifyUser(asset)
        }
    }
    
    #if DEBUG
    print(\"[インクリメンタル] 分析済み: \\(analyzedCount), スキップ: \\(skippedCount)\")
    print(\"[パフォーマンス] スキップ率: \\(Double(skippedCount)/Double(total) * 100)%\")
    #endif
    
    // 次のスキャンのためにタイムスタンプを更新
    saveLastSuccessfulScanDate(Date())
}

/// パフォーマンスメトリクス (実世界データ)
/// v1.7 (フルスキャン): 20枚の写真で28.4秒
/// v2.x (インクリメンタル): 20枚の写真で1.9秒 (99%キャッシュヒット)
/// 改善: 15倍高速、87%のバッテリー節約

インクリメンタルスキャン

  • 新規/変更された写真のみを分析
  • タイムスタンプベースのスキップロジック
  • 繰り返しスキャンでの大幅な時間節約
  • バッテリー消費量の削減
  • 効率的なメモリ使用量

スキップロジック

  • 高速タイムスタンプ比較
  • 変更日追跡
  • 範囲境界検証
  • 最小限の処理オーバーヘッド
  • 日常使用に最適化

ボールト暗号化

ChaCha20-Poly1305暗号化

> /Vault/VaultCrypto.swift AEAD暗号とハードウェア支援
import CryptoKit
		
		/// ボールトストレージ用のChaCha20-Poly1305暗号化
		/// キーはSecure Enclave保護付きのiOS Keychainに保存
		final class VaultCrypto {
		  
		  /// ChaCha20-Poly1305 AEADで写真データを暗号化
		  static func encryptData(_ data: Data, key: SymmetricKey) throws -> Data {
			  // ChaCha20-Poly1305は以下を提供:
			  // - 機密性 (暗号化)
			  // - 認証性 (HMAC)
			  // - 完全性 (改ざん検出)
			  let sealedBox = try ChaChaPoly.seal(data, using: key)
			  
			  return sealedBox.combined // ノンス + 暗号文 + タグ
		  }
		  
		  /// ボールトの写真を復号化
		  static func decryptData(_ encryptedData: Data, key: SymmetricKey) throws -> Data {
			  let sealedBox = try ChaChaPoly.SealedBox(combined: encryptedData)
			  let decryptedData = try ChaChaPoly.open(sealedBox, using: key)
			  
			  return decryptedData
		  }
		  
		  /// エントロピー検証付きの256ビット暗号化キーを生成 (v2.1.8+)
		  static func generateVaultKey() throws -> SymmetricKey {
			  let maxRetries = 3
			  
			  for attempt in 0..= 7.5 {
					  return key
				  }
				  
				  #if DEBUG
				  print("[暗号] 低エントロピーを検出、再試行 \(attempt + 1)/\(maxRetries)")
				  #endif
			  }
			  
			  throw CryptoError.insufficientEntropy
		  }
		}

なぜCHACHA20-POLY1305なのか?

  • ARM上でAESより高速 (ハードウェアAES不要)
  • 認証付き暗号化 (改ざんを検出)
  • Signal, WireGuard, TLS 1.3で使用
  • タイミング攻撃耐性
  • IETF標準 (RFC 8439)

キー保護

  • 256ビットキー (2^256の組み合わせ)
  • ハードウェア支援付きiOS Keychain
  • 暗号化されていない状態では永続化されない
  • デバイスのみ (バックアップ/同期なし)
  • エントロピー検証 (v2.1.8+)

仕様

技術詳細

コンポーネント 実装 セキュリティレベル
MLフレームワーク Apple SensitiveContentAnalysis (iOS 18+) ハードウェアアクセラレーション
暗号化アルゴリズム ChaCha20-Poly1305 AEAD 256ビットキー
キーストレージ iOS Keychain (セキュアエンクレーブ) ハードウェア支援
ファイル保護 .completeFileProtection iOSセキュアストレージ
スキャンパフォーマンス インクリメンタル (v2.0+) タイムスタンプスキップ付き 15倍高速
並行処理 デバイス対応 (A17+: 6スレッド, A15: 3, 旧機種: 1) 適応型
ネットワーク活動 なし (100% オフライン) クラウド露出ゼロ
ジェイルブレイク検出 信頼度スコアリング付き10ベクトル分析 プラットフォーム対応

脅威モデル

セキュリティ保証

保護済み

デバイス押収

ボールトは保存時に暗号化。FaceIDなしでは読み取り不可。

ネットワーク傍受

ネットワーク活動ゼロ。写真はデバイスを離れない。

クラウド侵害

クラウドストレージなし。すべてローカル。

バックアップ抽出

キーはデバイスにバインド。バックアップから抽出不可。

不正アクセス

生体認証+PINが必要。30秒後に自動ロック。

対象外

ロック解除されたデバイス

ボールトはロック解除された電話でも追加のFaceIDが必要。

物理的強制

強制的な生体認証ロック解除は防げません。

ジェイルブレイクされたデバイス

iOSセキュリティモデルが侵害されている(検出はするがブロックはしない)。

OSゼロデイ

未知のiOS脆弱性(すべてのアプリに影響)。

監査可能なコード

オープンソースセキュリティ

私たちの主張を検証

NuDefndrのコアプライバシーコンポーネントはGitHubでオープンソースです。 セキュリティ研究者は独立して以下を検証できます:

  • 分析中のネットワーク活動ゼロ (監査可能)
  • ChaCha20-Poly1305 暗号化実装
  • インクリメンタルスキャン アルゴリズムとスキップロジック
  • ジェイルブレイク検出 方法論
  • キーチェーン統合 とキーライフサイクル

送信終了

プライバシー第一のアーキテクチャ。 監査可能な実装。

← ホームに戻る