Cấu trúc file USBZ

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 header
  • UnwrapMasterKey(password, header) — Đăng nhập: derive passwordKey từ mật khẩu, giải mã encryptedMasterKey, trả về masterKey
  • WrapMasterKey(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 đến
  • UnwrapMasterKeyViaRecovery(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ần
  • DeriveMasterKey(recoveryKey, salt) — Internal: PBKDF2-HMAC-SHA256, 100.000 iterations, key 256-bit
  • DerivePasswordKey(password, salt) — Internal: PBKDF2-HMAC-SHA256, 100.000 iterations, key 256-bit
  • GenerateCounterNonce(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 vault
  • ZeroAllKeys() — Xóa sạch masterKey và passwordKey khỏi RAM bằng CryptographicOperations.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ùng string vì 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 bytes
  • Decrypt(ciphertext, key, nonce, authTag) — Giải mã AES-256-GCM, xác thực authTag trước, throw nếu tampered
  • WrapKey(keyToWrap, wrappingKey, nonce) — AES-GCM để wrap masterKey bằng passwordKey
  • UnwrapKey(wrappedKey, wrappingKey, nonce, authTag) — Giải mã wrapped key
  • HashPassword(password) — bcrypt hash để verify mật khẩu nhanh ở LoginWindow
  • VerifyPassword(password, bcryptHash) — Verify bcrypt
  • ComputeSHA256(data) — SHA-256 cho checksum header và Recovery Key hash
  • GenerateRandomBytes(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ọi KeyManager.InitializeKeys(), tạo metadata rỗng
  • OpenVault(vaultPath, password) — Mở vault: validate header, gọi KeyManager.UnwrapMasterKey(), load metadata
  • CloseVault() — Khóa vault: flush buffer, gọi KeyManager.ZeroAllKeys(), đóng file stream
  • IsVaultHealthy(vaultPath) — Kiểm tra vault trước khi mở: validate magic bytes, checksum, phát hiện corruption
  • RepairVault(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ọi AmsiScanner.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ừng
  • AddFiles(sourcePaths, destVaultPath, progress, cancellationToken) — Batch copy nhiều file, progress tính trên tổng kích thước
  • ExtractFile(vaultPath, destPath, progress, cancellationToken) — Copy file ra máy: giải mã từng chunk, ghi ra thư mục đích
  • DeleteFile(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 block
  • MoveFile(sourcePath, destPath) — Di chuyển trong vault: chỉ cập nhật ParentId trong metadata, không đụng data block
  • CreateFolder(vaultPath) — Thêm entry thư mục vào metadata
  • DeleteFolder(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 vault
  • GetUsedSpace() — Tổng kích thước data đang dùng
  • GetAvailableSpace() — Delegate sang DriveHelper.GetMaxContainerSize(), không tự tính

Chức năng — Mật khẩu:

  • ChangePassword(oldPassword, newPassword) — Verify mật khẩu cũ, gọi KeyManager.WrapMasterKey() với password mới, cập nhật header. Tức thì, không đụng data
  • ResetPasswordViaOtp(otpCode, newPassword) — Verify OTP, gọi KeyManager.WrapMasterKey(), cập nhật header
  • ResetPasswordViaRecoveryKey(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 checksum
  • ReadHeader(stream) — Đọc và parse toàn bộ header thành HeaderData object
  • ValidateHeader(header) — Kiểm tra magic bytes, version, checksum
  • UpdateFailureCount(stream, count) — Cập nhật chỉ failure_count, không viết lại toàn bộ header
  • UpdateEncryptedMasterKey(stream, newWrappedKey, newNonce, newTag) — Cập nhật chỉ phần key khi đổi mật khẩu
  • UpdateMetadataPointer(stream, length, nonce, tag) — Cập nhật con trỏ metadata sau mỗi thao tác file
  • IncrementNonceCounter(stream) — Tăng counter và ghi lại, gọi mỗi lần tạo nonce mới
  • IsCorrupted(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 blob
  • Deserialize(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 theo ParentId
  • FlattenTree(rootNode) — Chuyển cây về list flat để serialize
  • FindEntry(vaultPath) — Tìm FileEntry theo đường dẫn trong vault
  • FindChildren(parentId) — Lấy danh sách file/folder con trực tiếp
  • FindOrphanBlocks(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 RepairVault
  • AddEntry(entry) — Thêm entry mới vào danh sách
  • RemoveEntry(id) — Xóa entry khỏi danh sách
  • UpdateEntry(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ọi AmsiScanBuffer, trả về ScanResult
  • ScanBuffer(byte[] data, string contentName) — Quét buffer trực tiếp, dùng khi file đã trong memory
  • GetLastThreatName() — Tên mã độc nếu lần quét gần nhất phát hiện threat
  • IsAvailable() — 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() — Ghi HKCU\...\NoDriveTypeAutoRun = 0xFF vào Registry, lưu lại giá trị cũ
  • Restore() — Khôi phục Registry về giá trị cũ khi thoát app
  • IsBlocked() — Kiểm tra trạng thái hiện tại
  • BlockPermanent() — Tùy chọn: ghi vào HKLM để 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ạo usbz_log.db mã hóa, tạo bảng nếu chưa có
  • Log(EventType, detail) — Ghi 1 dòng log với timestamp và machine name
  • GetLogs(filter) — Truy vấn log theo EventType và khoảng thời gian
  • ExportCsv(outputPath, filter) — Xuất log ra file CSV
  • GetSessionSummary() — Tóm tắt phiên hiện tại: số file đã copy, số lần thao tác
  • Close() — Đó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 QRCoder hiể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 → FileDuplicateHandler nế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à raise PropertyChanged tự động
  • OnPropertyChanged(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.AvailableFreeSpace thời điểm thực, không cache
  • GetTotalSize(driveLetter) — Tổng dung lượng USB
  • GetMaxContainerSize(driveLetter)AvailableFreeSpace - 100MB — nguồn sự thật duy nhất cho con số này
  • WatchForEject(driveLetter, onEjectCallback) — Đăng ký WMI Win32_VolumeChangeEvent để phát hiện rút USB
  • StopWatching() — Hủy WMI watcher khi thoát app
  • IsUsbStillConnected(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)PasswordStrength enum: Weak / Medium / Strong / VeryStrong
  • GetPercent(password) → 0–100 để drive progress bar
  • GetLabel(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()string dạng USBZ-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ốc
  • Verify(inputKey, storedHash) → so sánh hash
  • Format(rawKey) → thêm dấu gạch ngang cho đẹp
  • Normalize(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 file
  • GetColor(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ạt
  • GetFileTypeLabel(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) → bool
  • GetResolution(fileName) → hiện dialog hỏi người dùng, trả về DuplicateResolution enum
  • DuplicateResolution enum: Overwrite / Rename / Skip
  • GenerateNewName(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ó conststatic 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ómSố fileVai trò
Core6Vault, Crypto, Key Wrapping, Header, Metadata, Model file
Security2AMSI scanner, AutoRun blocker
Storage2Log SQLite, Model log
UI147 cửa sổ × (xaml + cs)
ViewModels6MVVM binding cho 6 window có logic
Helpers5Drive, Password, RecoveryKey, Icon, Duplicate
Models3Settings, ScanResult, CopyProgress

Viết một bình luận