技術文書
システムアーキテクチャ
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 暗号化実装
- • インクリメンタルスキャン アルゴリズムとスキップロジック
- • ジェイルブレイク検出 方法論
- • キーチェーン統合 とキーライフサイクル
送信終了
プライバシー第一のアーキテクチャ。 監査可能な実装。
← ホームに戻る