Cây thư mục
USBZ/
│
├── USBZ.exe ← File duy nhất người dùng cần
│
├── Core/
│ ├── VaultEngine.cs
│ ├── CryptoService.cs
│ ├── ContainerHeader.cs
│ ├── MetadataStore.cs
│ ├── FileEntry.cs
│ └── KeyManager.cs ← MỚI
│
├── Security/
│ ├── AmsiScanner.cs
│ └── AutoRunBlocker.cs
│
├── Storage/
│ ├── LogService.cs
│ └── LogEntry.cs
│
├── UI/
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── LoginWindow.xaml
│ ├── LoginWindow.xaml.cs
│ ├── SetupWizard.xaml
│ ├── SetupWizard.xaml.cs
│ ├── MainWindow.xaml
│ ├── MainWindow.xaml.cs
│ ├── ChangePasswordWindow.xaml
│ ├── ChangePasswordWindow.xaml.cs
│ ├── RecoverPasswordWindow.xaml
│ ├── RecoverPasswordWindow.xaml.cs
│ └── LogViewerWindow.xaml
│ └── LogViewerWindow.xaml.cs
│
├── ViewModels/
│ ├── BaseViewModel.cs ← MỚI
│ ├── LoginViewModel.cs
│ ├── SetupViewModel.cs
│ ├── MainViewModel.cs
│ ├── ChangePasswordViewModel.cs
│ ├── RecoverPasswordViewModel.cs ← MỚI (tách riêng)
│ └── LogViewerViewModel.cs
│
├── Helpers/
│ ├── DriveHelper.cs
│ ├── PasswordStrengthHelper.cs
│ ├── RecoveryKeyGenerator.cs
│ ├── FileIconHelper.cs ← MỚI
│ └── FileDuplicateHandler.cs ← MỚI
│
└── Models/
├── AppSettings.cs
├── ScanResult.cs ← MỚI (tách ra khỏi AmsiScanner)
└── CopyProgress.cs ← MỚI
Mô tả chi tiết từng file
USBZ.exe
File portable duy nhất người dùng cần. Build bằng .NET 8 PublishSingleFile=true + SelfContained=true. Chứa toàn bộ runtime, không cần cài đặt thêm bất cứ thứ gì. Kích thước khoảng 50–80MB.
CORE/
Core/KeyManager.cs
Vai trò: Quản lý toàn bộ vòng đời key theo kiến trúc Key Wrapping. Đây là file quan trọng nhất về mặt bảo mật — mọi key đều đi qua đây, không có file nào khác tự tạo hay lưu key.
Kiến trúc Key Wrapping:
Recovery Key (cố định mãi mãi)
└→ masterKey = PBKDF2(recoveryKey, salt_recovery)
└→ Mã hóa toàn bộ Data.usbz
Mật khẩu người dùng
└→ passwordKey = PBKDF2(password, salt_password)
└→ encryptedMasterKey = AES_Wrap(masterKey, passwordKey)
└→ Chỉ lưu encryptedMasterKey trong header
Chức năng:
InitializeKeys(recoveryKey, password)— Lần đầu setup: tạo masterKey từ Recovery Key, wrap bằng password, lưu vào headerUnwrapMasterKey(password, header)— Đăng nhập: derive passwordKey từ mật khẩu, giải mã encryptedMasterKey, trả về masterKeyWrapMasterKey(masterKey, newPassword)— Đổi mật khẩu: wrap lại masterKey bằng password mới, chỉ cập nhật vài bytes trong header. Container không bị đụng đếnUnwrapMasterKeyViaRecovery(recoveryKey, header)— Khôi phục: dùng Recovery Key để lấy lại masterKey khi quên mật khẩu hoặc sai 5 lầnDeriveMasterKey(recoveryKey, salt)— Internal: PBKDF2-HMAC-SHA256, 100.000 iterations, key 256-bitDerivePasswordKey(password, salt)— Internal: PBKDF2-HMAC-SHA256, 100.000 iterations, key 256-bitGenerateCounterNonce(seed, counter)— Tạo nonce 12 bytes = 4 bytes random seed + 8 bytes counter tăng dần, đảm bảo không bao giờ trùng trong cùng vaultZeroAllKeys()— Xóa sạch masterKey và passwordKey khỏi RAM bằngCryptographicOperations.ZeroMemory(). Gọi khi đóng vault hoặc thoát app
Lưu ý quan trọng:
- masterKey chỉ tồn tại trong RAM khi vault đang mở, không bao giờ lưu xuống disk dạng plaintext
- Mọi key đều là
byte[], không dùngstringvì string không ZeroMemory được
Core/CryptoService.cs
Vai trò: Thực hiện các phép toán mã hóa/giải mã thuần túy. Không biết gì về key management, chỉ nhận key vào và trả về kết quả. Mọi thuật toán crypto đều tập trung tại đây.
Chức năng:
Encrypt(plaintext, key, nonce, out authTag)— AES-256-GCM, trả về ciphertext + authTag 16 bytesDecrypt(ciphertext, key, nonce, authTag)— Giải mã AES-256-GCM, xác thực authTag trước, throw nếu tamperedWrapKey(keyToWrap, wrappingKey, nonce)— AES-GCM để wrap masterKey bằng passwordKeyUnwrapKey(wrappedKey, wrappingKey, nonce, authTag)— Giải mã wrapped keyHashPassword(password)— bcrypt hash để verify mật khẩu nhanh ở LoginWindowVerifyPassword(password, bcryptHash)— Verify bcryptComputeSHA256(data)— SHA-256 cho checksum header và Recovery Key hashGenerateRandomBytes(length)—RandomNumberGenerator.GetBytes()dùng cho salt, seed
Không có trong file này:
- Không có key derivation (PBKDF2) — việc của
KeyManager - Không có nonce generation — việc của
KeyManager - Không có ZeroMemory — việc của
KeyManager
Core/VaultEngine.cs
Vai trò: Điều phối toàn bộ hoạt động của container Data.usbz. Gọi KeyManager, CryptoService, ContainerHeader, MetadataStore để thực hiện các thao tác file. Đây là API chính mà các ViewModel gọi vào.
Chức năng — Vòng đời vault:
CreateVault(vaultPath, recoveryKey, password)— Tạo Data.usbz mới: khởi tạo header, gọiKeyManager.InitializeKeys(), tạo metadata rỗngOpenVault(vaultPath, password)— Mở vault: validate header, gọiKeyManager.UnwrapMasterKey(), load metadataCloseVault()— Khóa vault: flush buffer, gọiKeyManager.ZeroAllKeys(), đóng file streamIsVaultHealthy(vaultPath)— Kiểm tra vault trước khi mở: validate magic bytes, checksum, phát hiện corruptionRepairVault(vaultPath)— Dọn dẹp orphan block (block không có entry trong metadata), xóa luôn không khôi phục, trả về số block đã xóa
Chức năng — Thao tác file:
AddFile(sourcePath, destVaultPath, progress, cancellationToken)— Copy file vào vault: gọiAmsiScanner.ScanFile()trước, kiểm tra available space, mã hóa từng chunk, ghi block, cập nhật metadata. Hỗ trợ progress callback và hủy giữa chừngAddFiles(sourcePaths, destVaultPath, progress, cancellationToken)— Batch copy nhiều file, progress tính trên tổng kích thướcExtractFile(vaultPath, destPath, progress, cancellationToken)— Copy file ra máy: giải mã từng chunk, ghi ra thư mục đíchDeleteFile(vaultPath)— Xóa file: xóa entry khỏi metadata, đánh dấu block là free (không xóa data thực để tránh delay)RenameFile(vaultPath, newName)— Đổi tên: chỉ cập nhật metadata, không đụng data blockMoveFile(sourcePath, destPath)— Di chuyển trong vault: chỉ cập nhật ParentId trong metadata, không đụng data blockCreateFolder(vaultPath)— Thêm entry thư mục vào metadataDeleteFolder(vaultPath)— Xóa thư mục và toàn bộ nội dung đệ quy
Chức năng — Thông tin:
ListFiles(vaultPath)— Trả vềList<FileEntry>trong một thư mục cụ thểGetFileCount()— Tổng số file trong vaultGetUsedSpace()— Tổng kích thước data đang dùngGetAvailableSpace()— Delegate sangDriveHelper.GetMaxContainerSize(), không tự tính
Chức năng — Mật khẩu:
ChangePassword(oldPassword, newPassword)— Verify mật khẩu cũ, gọiKeyManager.WrapMasterKey()với password mới, cập nhật header. Tức thì, không đụng dataResetPasswordViaOtp(otpCode, newPassword)— Verify OTP, gọiKeyManager.WrapMasterKey(), cập nhật headerResetPasswordViaRecoveryKey(recoveryKey, newPassword)— Verify Recovery Key, unwrap masterKey bằng Recovery Key, wrap lại bằng password mới
Lưu ý quan trọng:
- Write-ahead: cập nhật metadata trước khi return success, không ghi kiểu “data trước, metadata sau”
- Mọi thao tác ghi đều kiểm tra
GetAvailableSpace()trước - AMSI chỉ quét chiều VÀO, không quét chiều RA
Core/ContainerHeader.cs
Vai trò: Định nghĩa cấu trúc và đọc/ghi phần header cố định của Data.usbz. Chỉ xử lý header — không biết gì về metadata hay data block.
Cấu trúc header (bytes):
[0-3] Magic: "USBZ"
[4-5] Version: 0x0001
[6-37] salt_recovery (32 bytes)
[38-69] salt_password (32 bytes)
[70-85] nonce_master_key (16 bytes)
[86-117] encrypted_master_key (32 bytes)
[118-133] auth_tag_master_key (16 bytes)
[134-165] recovery_key_hash SHA-256 (32 bytes)
[166-169] failure_count (4 bytes)
[170-205] bcrypt_hash mật khẩu (36 bytes)
[206-237] totp_secret mã hóa (32 bytes)
[238-249] nonce_totp (12 bytes)
[250-265] auth_tag_totp (16 bytes)
[266-269] nonce_counter_seed (4 bytes)
[270-273] nonce_counter current value (8 bytes)
[278-281] metadata_length (4 bytes)
[282-297] nonce_metadata (16 bytes)
[298-313] auth_tag_metadata (16 bytes)
[314...] metadata block (mã hóa, độ dài variable)
Chức năng:
WriteHeader(stream, headerData)— Ghi header vào đầu file, tính và ghi checksumReadHeader(stream)— Đọc và parse toàn bộ header thànhHeaderDataobjectValidateHeader(header)— Kiểm tra magic bytes, version, checksumUpdateFailureCount(stream, count)— Cập nhật chỉ failure_count, không viết lại toàn bộ headerUpdateEncryptedMasterKey(stream, newWrappedKey, newNonce, newTag)— Cập nhật chỉ phần key khi đổi mật khẩuUpdateMetadataPointer(stream, length, nonce, tag)— Cập nhật con trỏ metadata sau mỗi thao tác fileIncrementNonceCounter(stream)— Tăng counter và ghi lại, gọi mỗi lần tạo nonce mớiIsCorrupted(stream)— Kiểm tra magic bytes và checksum cơ bản
Core/MetadataStore.cs
Vai trò: Quản lý cây thư mục và danh sách FileEntry trong metadata block của container. Là nguồn sự thật duy nhất về “có những file gì trong vault”.
Chức năng:
Serialize(List<FileEntry> entries, masterKey, nonce)— Chuyển danh sách thành JSON → mã hóa AES-256-GCM → trả về encrypted blobDeserialize(encryptedBlob, masterKey, nonce, authTag)— Giải mã → parse JSON → trả vềList<FileEntry>BuildTree(List<FileEntry>)— Dựng cây thư mục từ danh sách flat, dựa theoParentIdFlattenTree(rootNode)— Chuyển cây về list flat để serializeFindEntry(vaultPath)— Tìm FileEntry theo đường dẫn trong vaultFindChildren(parentId)— Lấy danh sách file/folder con trực tiếpFindOrphanBlocks(entries, dataBlockOffsets)— So sánh danh sách entry với danh sách block thực tế trong file, trả về các block không có entry → dùng cho RepairVaultAddEntry(entry)— Thêm entry mới vào danh sáchRemoveEntry(id)— Xóa entry khỏi danh sáchUpdateEntry(entry)— Cập nhật entry đã có
Core/FileEntry.cs
Vai trò: Model đại diện một file hoặc thư mục trong vault. Pure data class, không có logic.
Fields:
string Id // GUID duy nhất
string Name // Tên file hoặc thư mục
string VaultPath // Đường dẫn đầy đủ trong vault: /HoSo/file.pdf
bool IsFolder
long OriginalSize // Kích thước trước mã hóa
long EncryptedSize // Kích thước sau mã hóa
DateTime CreatedAt
DateTime ModifiedAt
long BlockOffset // Vị trí bắt đầu của data block trong Data.usbz
long BlockLength // Độ dài block (= EncryptedSize)
byte[] BlockNonce // 12 bytes nonce của block này (counter-based)
byte[] BlockAuthTag // 16 bytes GCM auth tag
string ParentId // Id của thư mục cha, null nếu là root
bool IsDeleted // Soft delete flag (để thu hồi space sau)
SECURITY/
Security/AmsiScanner.cs
Vai trò: Quét virus file trước khi copy vào vault. Dùng Windows AMSI API để tận dụng Windows Defender mà không cần engine riêng. Chỉ quét chiều VÀO — file đã trong vault không quét lại khi copy ra.
Chức năng:
Initialize()— Khởi tạo AMSI context:AmsiInitialize("USBZ", out context)ScanFile(filePath)— Đọc toàn bộ file, gọiAmsiScanBuffer, trả vềScanResultScanBuffer(byte[] data, string contentName)— Quét buffer trực tiếp, dùng khi file đã trong memoryGetLastThreatName()— Tên mã độc nếu lần quét gần nhất phát hiện threatIsAvailable()— Kiểm tra AMSI có sẵn trên máy không (Windows 10+ luôn có)Cleanup()—AmsiUninitialize(context)khi đóng app
P/Invoke:
[DllImport("amsi.dll")]
AmsiInitialize, AmsiScanBuffer, AmsiUninitialize, AmsiOpenSession, AmsiCloseSession
Kết quả trả về: ScanResult enum trong Models/ScanResult.cs
Security/AutoRunBlocker.cs
Vai trò: Vô hiệu hóa AutoRun/AutoPlay ngay khi USBZ khởi động để ngăn mã độc tự chạy từ USB.
Chức năng:
Block()— GhiHKCU\...\NoDriveTypeAutoRun = 0xFFvào Registry, lưu lại giá trị cũRestore()— Khôi phục Registry về giá trị cũ khi thoát appIsBlocked()— Kiểm tra trạng thái hiện tạiBlockPermanent()— Tùy chọn: ghi vàoHKLMđể block toàn hệ thống (cần quyền admin)
STORAGE/
Storage/LogService.cs
Vai trò: Ghi và đọc log hoạt động. Lưu trong file SQLite mã hóa bằng SQLCipher, đặt cạnh Data.usbz trong USB. Log chạy hoàn toàn ngầm, không hiện ra trừ khi vào Menu → Xem log.
Chức năng:
Initialize(dbPath, masterKey)— Mở hoặc tạousbz_log.dbmã hóa, tạo bảng nếu chưa cóLog(EventType, detail)— Ghi 1 dòng log với timestamp và machine nameGetLogs(filter)— Truy vấn log theo EventType và khoảng thời gianExportCsv(outputPath, filter)— Xuất log ra file CSVGetSessionSummary()— Tóm tắt phiên hiện tại: số file đã copy, số lần thao tácClose()— Đóng kết nối SQLite
EventType enum:
Login, LoginFailed, LoginLocked, LoginUnlocked,
PasswordChanged, PasswordReset,
FileCopiedIn, FileCopiedOut, FileDeleted,
FileRenamed, FileMoved, FolderCreated, FolderDeleted,
ScanThreatFound, ScanClean,
VaultRepaired, SessionEnd
Schema:
CREATE TABLE logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TEXT NOT NULL,
event_type TEXT NOT NULL,
detail TEXT,
machine_name TEXT
)
Storage/LogEntry.cs
Vai trò: Model cho một dòng log. Pure data class.
int Id
DateTime Timestamp
string EventType
string Detail
string MachineName
UI/
UI/App.xaml + App.xaml.cs
Vai trò: Điểm khởi động duy nhất của ứng dụng. Quyết định mở window nào đầu tiên dựa trên trạng thái USB.
Logic khởi động:
App.OnStartup()
→ AutoRunBlocker.Block()
→ DriveHelper.GetUsbDriveLetter()
→ Kiểm tra Data.usbz có tồn tại không
Không có → mở SetupWizard
Có → VaultEngine.IsVaultHealthy()
Healthy → mở LoginWindow
Corrupted → hiện dialog lỗi
"Tạo vault mới" → xóa Data.usbz cũ → mở SetupWizard
"Thoát" → đóng app
→ Đăng ký handler cho app shutdown: gọi VaultEngine.CloseVault() + AutoRunBlocker.Restore()
→ Đăng ký handler cho USB eject: WMI event → tự động CloseVault + thông báo
UI/LoginWindow.xaml + LoginWindow.xaml.cs
Vai trò: Màn hình đăng nhập, hiện mỗi lần cắm USB.
UI:
- Header teal: logo USBZ, tên file Data.usbz, dung lượng USB
- Ô nhập mật khẩu + nút show/hide
- Nút “Mở khoá”
- Link “Quên mật khẩu?” → mở RecoverPasswordWindow
- Link “Dùng Recovery Key” → inline prompt nhập Recovery Key
- Box cảnh báo đỏ: hiện khi sai mật khẩu, ghi rõ còn N lần
- Box thông tin 3 lớp bảo vệ (màu xanh/vàng/đỏ)
- Khi
IsLocked() = true: disable ô mật khẩu, chỉ cho dùng Recovery Key
Logic:
- Gọi
VaultEngine.OpenVault()→ thành công → mở MainWindow → đóng LoginWindow - Sai → cập nhật failure count, hiện cảnh báo
- Sai 5 lần → disable form, chỉ còn Recovery Key
UI/SetupWizard.xaml + SetupWizard.xaml.cs
Vai trò: Wizard 3 bước chỉ chạy 1 lần khi chưa có Data.usbz.
Bước 1 — Tạo mật khẩu:
- 2 ô mật khẩu + xác nhận
- Thanh đo độ mạnh realtime (gọi
PasswordStrengthHelper) - Validation: khớp nhau, tối thiểu 10 ký tự, tối thiểu “Trung bình”
- Hiển thị: “USB còn X GB · Container có thể dùng tối đa Y GB” (gọi
DriveHelper.GetMaxContainerSize()động)
Bước 2 — Google Authenticator:
- Gọi
AuthService.SetupTotp()lấy secret + otpauth URI - Render QR bằng
QRCoderhiển thị trong Image control - Ô nhập mã 6 số
- Countdown 30 giây cho mã hiện tại
- Gọi
AuthService.VerifyTotp()để xác nhận
Bước 3 — Recovery Key:
- Gọi
RecoveryKeyGenerator.Generate()lấy key - Hiển thị dạng monospace:
USBZ-XXXX-XXXX-XXXX - Nút Sao chép:
Clipboard.SetText() - Nút In:
PrintDialog - Checkbox bắt buộc tích trước khi nút “Hoàn tất” active
- Cảnh báo rõ: “Mất key này = mất toàn bộ dữ liệu vĩnh viễn”
Bấm Hoàn tất:
- Gọi
VaultEngine.CreateVault()với password và recovery key - Mở MainWindow → đóng SetupWizard
UI/MainWindow.xaml + MainWindow.xaml.cs
Vai trò: Giao diện làm việc chính hàng ngày. 2 cột file + cột giữa copy.
Header:
- Badge “Đã quét sạch” / “Đang quét…” (cập nhật khi scan)
- Tên Data.usbz
- Thanh dung lượng:
GetUsedSpace() / GetAvailableSpace()gọi động mỗi khi có thay đổi - Menu button → dropdown: Đổi mật khẩu | Xem log | Khoá USB ngay
- Nút X: gọi
CloseVault()+ZeroAllKeys()+ đóng app
Cột trái — Máy tính:
- Dropdown: Desktop / C:\ / C:\Downloads / C:\Documents / D:\ / Chọn thư mục…
- Breadcrumb đường dẫn hiện tại
- Toolbar: + Thư mục | Xóa | Đổi tên | Refresh | Tìm kiếm
- Dòng “…” đầu danh sách (ẩn khi đang ở root)
- ListView: icon màu (từ
FileIconHelper), tên, kích thước, ngày sửa - Multi-select: Ctrl+Click, Shift+Click
- Double-click thư mục: đi vào thư mục đó
Cột giữa:
- Nút → (copy vào USB): active khi đã chọn ít nhất 1 file ở cột trái
- Nút ← (copy ra máy): active khi đã chọn ít nhất 1 file ở cột phải
- Progress bar nhỏ xuất hiện khi đang copy
Cột phải — USB:
- Badge AES-256
- Breadcrumb:
Data.usbz / subfolder / ... - Toolbar: + Thư mục | Xóa | Đổi tên | Refresh | Tìm kiếm
- Dòng “…” đầu danh sách (ẩn khi đang ở root vault)
- ListView: icon màu, tên, kích thước, ngày sửa
- Multi-select
Status bar:
- “Chọn file rồi bấm mũi tên · Không thể mở hoặc chạy file trực tiếp”
- Đồng hồ phiên làm việc (DispatcherTimer trong MainViewModel)
- Đèn xanh + “Đang kết nối”
Logic copy:
- Copy vào:
AmsiScanner.ScanFile()→ nếu threat → hiện cảnh báo, hủy copy → nếu clean →VaultEngine.AddFiles()với progress →FileDuplicateHandlernếu trùng tên → Refresh cột phải - Copy ra:
VaultEngine.ExtractFile()với progress → Refresh cột trái - Xóa: xác nhận dialog →
VaultEngine.DeleteFile()→ Refresh - Đổi tên: inline edit →
VaultEngine.RenameFile()→ Refresh - Double-click thư mục USB: navigate vào thư mục đó, cập nhật breadcrumb
UI/ChangePasswordWindow.xaml + ChangePasswordWindow.xaml.cs
Vai trò: Đổi mật khẩu khi đang dùng. 2 bước tuần tự.
Bước 1: Nhập mật khẩu hiện tại → CryptoService.VerifyPassword()
Bước 2: Nhập mật khẩu mới + xác nhận + thanh đo độ mạnh → VaultEngine.ChangePassword() → tức thì vì chỉ wrap lại masterKey → thông báo thành công → đóng window
Lưu ý: Không còn cần progress bar vì Key Wrapping giải quyết vấn đề ReEncrypt chậm.
UI/RecoverPasswordWindow.xaml + RecoverPasswordWindow.xaml.cs
Vai trò: Khôi phục mật khẩu. Xử lý 2 trường hợp: quên mật khẩu (dùng OTP) và mất OTP (dùng Recovery Key).
UI:
- Tab 1 — Dùng Google Authenticator:
- Ô nhập OTP 6 số
- Countdown 30 giây
- Gọi
VaultEngine.ResetPasswordViaOtp()
- Tab 2 — Dùng Recovery Key:
- Ô nhập Recovery Key dạng USBZ-XXXX-XXXX-XXXX
- Gọi
VaultEngine.ResetPasswordViaRecoveryKey()
- Sau khi xác minh thành công cả 2 tab: hiện form đặt mật khẩu mới
Giải quyết mâu thuẫn logic đã phát hiện: Recovery Key có thể dùng để reset mật khẩu, không chỉ mở khóa khi sai 5 lần.
UI/LogViewerWindow.xaml + LogViewerWindow.xaml.cs
Vai trò: Xem lịch sử hoạt động của USB.
UI:
- Bảng log: Thời gian | Sự kiện | Chi tiết | Tên máy
- Filter: dropdown loại sự kiện + date picker từ/đến
- Nút Refresh tải lại
- Nút Export CSV →
LogService.ExportCsv() - Tóm tắt phiên hiện tại ở trên cùng
VIEWMODELS/
ViewModels/BaseViewModel.cs
Vai trò: Class cha cho tất cả ViewModel. Implement INotifyPropertyChanged để tránh lặp code.
Chức năng:
SetProperty<T>(ref T field, T value, [CallerMemberName] string name)— Set property và raisePropertyChangedtự độngOnPropertyChanged(string name)— Raise event thủ công khi cần
ViewModels/LoginViewModel.cs
Binding cho LoginWindow. Xử lý: nhập mật khẩu, gọi OpenVault, đếm lần sai, trạng thái locked, điều hướng sang MainWindow hoặc RecoverPasswordWindow.
ViewModels/SetupViewModel.cs
Binding cho SetupWizard. Xử lý: 3 bước wizard, validation mật khẩu, setup TOTP, generate Recovery Key, gọi CreateVault, điều hướng sang MainWindow.
ViewModels/MainViewModel.cs
Binding cho MainWindow. Xử lý:
- Danh sách file 2 cột (ObservableCollection)
- Navigation breadcrumb cả 2 cột
- Selected items cả 2 cột
- Commands: Copy vào, Copy ra, Xóa, Đổi tên, Tạo thư mục, Refresh cả 2
- Progress copy (CopyProgress binding)
- SessionTimer:
DispatcherTimerđếm thời gian phiên làm việc - Dung lượng động: cập nhật mỗi khi có thao tác file
ViewModels/ChangePasswordViewModel.cs
Binding cho ChangePasswordWindow. Xử lý 2 bước, validation, gọi VaultEngine.ChangePassword().
ViewModels/RecoverPasswordViewModel.cs
Binding cho RecoverPasswordWindow. Xử lý 2 tab (OTP và Recovery Key), countdown timer, form đặt mật khẩu mới.
ViewModels/LogViewerViewModel.cs
Binding cho LogViewerWindow. Load log, filter, export CSV.
HELPERS/
Helpers/DriveHelper.cs
Vai trò: Mọi thông tin liên quan đến ổ đĩa USB đều đi qua đây.
Chức năng:
GetUsbDriveLetter()— Tìm ổ đĩa chứa USBZ.exe đang chạy:Path.GetPathRoot(AppContext.BaseDirectory)GetAvailableFreeSpace(driveLetter)—DriveInfo.AvailableFreeSpacethời điểm thực, không cacheGetTotalSize(driveLetter)— Tổng dung lượng USBGetMaxContainerSize(driveLetter)—AvailableFreeSpace - 100MB— nguồn sự thật duy nhất cho con số nàyWatchForEject(driveLetter, onEjectCallback)— Đăng ký WMIWin32_VolumeChangeEventđể phát hiện rút USBStopWatching()— Hủy WMI watcher khi thoát appIsUsbStillConnected(driveLetter)— Kiểm tra nhanh USB còn cắm không
Helpers/PasswordStrengthHelper.cs
Vai trò: Đánh giá độ mạnh mật khẩu để hiển thị realtime trong SetupWizard và ChangePasswordWindow.
Chức năng:
Evaluate(password)→PasswordStrengthenum:Weak / Medium / Strong / VeryStrongGetPercent(password)→ 0–100 để drive progress barGetLabel(password)→ string hiển thị: “Yếu / Trung bình / Mạnh / Rất mạnh”GetColor(password)→ màu hex tương ứng: đỏ / vàng / xanh lá / xanh đậm
Tiêu chí: độ dài ≥ 10, có chữ hoa, có chữ thường, có số, có ký tự đặc biệt.
Helpers/RecoveryKeyGenerator.cs
Vai trò: Tạo và xác minh Recovery Key.
Chức năng:
Generate()→stringdạngUSBZ-XXXX-XXXX-XXXX(16 bytes random từRandomNumberGenerator, encode Base32)Hash(recoveryKey)→ SHA-256 hash để lưu vào header, không lưu key gốcVerify(inputKey, storedHash)→ so sánh hashFormat(rawKey)→ thêm dấu gạch ngang cho đẹpNormalize(inputKey)→ bỏ dấu gạch ngang, uppercase để so sánh
Helpers/FileIconHelper.cs
Vai trò: Trả về icon và màu tương ứng theo đuôi file để hiển thị trong ListView.
Chức năng:
GetIcon(fileName)→ SVG path string tương ứng loại fileGetColor(fileName)→ màu hex: .pdf=đỏ, .xlsx/.xls=xanh lá, .docx/.doc=xanh dương, .jpg/.png=cam, .zip/.rar=xám, .exe=đỏ đậm, khác=xám nhạtGetFileTypeLabel(fileName)→ “PDF Document”, “Excel File”…
Helpers/FileDuplicateHandler.cs
Vai trò: Xử lý trường hợp copy file vào vault khi đã có file cùng tên.
Chức năng:
CheckDuplicate(vaultPath, fileName)→ boolGetResolution(fileName)→ hiện dialog hỏi người dùng, trả vềDuplicateResolutionenumDuplicateResolutionenum:Overwrite / Rename / SkipGenerateNewName(fileName)→ tạo tên mới:file (1).pdf,file (2).pdf…
MODELS/
Models/AppSettings.cs
Vai trò: Hằng số toàn ứng dụng. Không có logic, chỉ có const và static readonly.
const string ContainerFileName = "Data.usbz";
const string LogFileName = "usbz_log.db";
const string AppName = "USBZ";
const string MagicBytes = "USBZ";
const int ContainerVersion = 1;
const int MaxLoginAttempts = 5;
const long ReservedSpaceBytes = 100L * 1024 * 1024; // 100MB
const int PbkdfIterations = 100_000;
const int MinPasswordLength = 10;
const int AesKeySize = 32; // 256 bits
const int GcmNonceSize = 12; // bytes
const int GcmTagSize = 16; // bytes
const int SaltSize = 32; // bytes
const int NonceSeedSize = 4; // bytes
const int ChunkSize = 4096; // bytes per encrypt chunk
Models/ScanResult.cs
Vai trò: Kết quả quét AMSI. Tách ra khỏi AmsiScanner để ViewModel có thể dùng mà không phụ thuộc vào Security layer.
enum ScanResultType { Clean, Threat, Error, Unavailable }
class ScanResult {
ScanResultType Type
string ThreatName // null nếu Clean
string FilePath
TimeSpan ScanDuration
}
Models/CopyProgress.cs
Vai trò: Truyền thông tin tiến độ copy từ VaultEngine lên UI.
class CopyProgress {
string CurrentFileName
int CurrentFilePercent // 0-100 của file hiện tại
int TotalFilesCount
int CompletedFilesCount
int OverallPercent // 0-100 tổng thể
long BytesTransferred
long TotalBytes
bool IsCancelled
}
Tổng kết — 35 file, không trùng, không thiếu
| Nhóm | Số file | Vai trò |
|---|---|---|
| Core | 6 | Vault, Crypto, Key Wrapping, Header, Metadata, Model file |
| Security | 2 | AMSI scanner, AutoRun blocker |
| Storage | 2 | Log SQLite, Model log |
| UI | 14 | 7 cửa sổ × (xaml + cs) |
| ViewModels | 6 | MVVM binding cho 6 window có logic |
| Helpers | 5 | Drive, Password, RecoveryKey, Icon, Duplicate |
| Models | 3 | Settings, ScanResult, CopyProgress |