Knowledge Base

A transparent look at how Vault3R works under the hood. We publish selected source code to let you verify our security claims. No black boxes — just standard, auditable cryptography.

🔒 Only safe-to-share portions are published. No secrets, keys, or internal APIs are exposed.

Contents

  1. Application architecture
  2. Data models
  3. Vault encryption (AES-256-GCM)
  4. Encrypted device sync
  5. Pairing protocol

🏗️Application Architecture

Vault3R is built with .NET 8 (WPF) on Windows and Kotlin (Jetpack Compose) on Android. The codebase follows a service-oriented pattern — each responsibility lives in a dedicated static or singleton service.

🔐

CryptoService

AES-256-GCM encryption/decryption, PBKDF2 key derivation, password hashing, constant-time comparison.

🗄️

DatabaseService

Encrypted vault storage on disk — load, save, merge. Binary .vlt.db container with integrity checks.

📲

DevicePairingService

Multi-device pairing — key generation, QR exchange, channel derivation, E2E encrypted confirmation.

🔄

ExportImportService

CSV/JSON import, .vlt backup & restore, merge/overwrite modes, encoding auto-detection.

💪

PasswordStrengthService

Real-time password strength scoring — entropy calculation, pattern detection, dictionary checks.

📋

ClipboardService

Secure clipboard operations — copy with auto-clear after 30 seconds, preventing clipboard history leaks.

🔑

LicenseService

Device-bound license validation via Hardware ID. Checks activation status against the license server.

💾

AutoBackupService

Automatic encrypted .vlt backups on schedule — configurable interval, retention policy, background operation.

📦Data Models

Vault3R stores two types of encrypted records: password entries and secure notes. Both support tagging and are serialized as JSON before encryption.

Models/PasswordEntry.cs C#
public class PasswordEntry : INotifyPropertyChanged
{
    public string Name { get; set; } = string.Empty;
    public string Username { get; set; } = string.Empty;
    public string Password { get; set; } = string.Empty;
    public string Url { get; set; } = string.Empty;
    public string Category { get; set; } = string.Empty;
    public List<string> Tags { get; set; } = new List<string>();
    public string Notes { get; set; } = string.Empty;
    public bool IsFavorite { get; set; } = false;

    [JsonIgnore]
    public string TagsDisplay => Tags == null
        ? string.Empty
        : string.Join(", ", Tags
            .Where(t => !string.IsNullOrWhiteSpace(t))
            .Select(t => t.Trim()));
}
Models/SecureNote.cs C#
public class SecureNote
{
    public string Id { get; set; } = Guid.NewGuid().ToString("N");
    public string Title { get; set; } = string.Empty;
    public string Content { get; set; } = string.Empty;
    public List<string> Tags { get; set; } = new List<string>();
    public DateTime CreatedUtc { get; set; } = DateTime.UtcNow;
    public DateTime UpdatedUtc { get; set; } = DateTime.UtcNow;

    [JsonIgnore]
    public string TagsDisplay => Tags == null
        ? string.Empty
        : string.Join(", ", Tags
            .Where(t => !string.IsNullOrWhiteSpace(t))
            .Select(t => t.Trim()));
}
Note: Both models are serialized to JSON and then encrypted with AES-256-GCM before being written to the vault file. The Password field in PasswordEntry is additionally encrypted per-entry with the master password.

🔐Vault Encryption

Vault3R uses industry-standard AES-256-GCM for authenticated encryption. The encryption key is derived from your master password using PBKDF2 with a random salt and high iteration count. No secrets are stored on disk — only the derived verifier and encrypted ciphertext.

Services/CryptoService.cs — constants C#
public static class CryptoService
{
    private const int KeySize = 256;            // AES-256
    private const int V2IterationCount = 200000; // PBKDF2 iterations
    private const int V2SaltSizeBytes = 16;      // 128-bit random salt
    private const int V2NonceSizeBytes = 12;     // 96-bit GCM nonce
    private const int V2TagSizeBytes = 16;       // 128-bit auth tag
}
Services/CryptoService.cs — password verifier C#
/// <summary>
/// Creates a password verifier (stored on disk to validate unlock).
/// Format: v2$pbkdf2-sha256$iterations$salt_b64$hash_b64
/// The master password itself is never stored.
/// </summary>
public static string CreatePasswordVerifier(string password)
{
    var salt = RandomNumberGenerator.GetBytes(V2SaltSizeBytes);
    var key = DeriveKeyPbkdf2(password, salt, V2IterationCount);

    var saltB64 = Convert.ToBase64String(salt);
    var hashB64 = Convert.ToBase64String(key);
    return $"v2$pbkdf2-sha256${V2IterationCount}${saltB64}${hashB64}";
}

/// <summary>
/// Constant-time password comparison to prevent timing side-channel attacks.
/// </summary>
public static bool VerifyPassword(string password, string hash)
{
    var a = Encoding.UTF8.GetBytes(HashPassword(password));
    var b = Encoding.UTF8.GetBytes(hash);
    if (a.Length != b.Length) return false;
    return CryptographicOperations.FixedTimeEquals(a, b);
}
Encryption pipeline: Master password → PBKDF2 (200k iterations, random salt) → 256-bit key → AES-256-GCM (random nonce, AAD) → salt + nonce + auth_tag + ciphertext stored on disk. Decryption verifies the authentication tag before returning any plaintext — any tampering is detected and rejected.

🔄Encrypted Device Sync

Vault3R syncs between Windows and Android through an ephemeral relay. All data is end-to-end encrypted with a shared 256-bit key — the relay only handles opaque ciphertext and purges it immediately after download.

🔑

Key generation

256-bit key via CSPRNG. Never leaves the devices.

📲

QR exchange

Key transferred via QR code scan. No network involved.

🔒

AES-GCM encrypt

Vault encrypted locally before upload to relay.

🗑️

Deliver & purge

Receiver decrypts. Relay data auto-deleted.

Services/DevicePairingService.cs — channel derivation C#
/// <summary>
/// Computes channel ID from a raw pairing key.
/// channel = HMAC-SHA256(pairingKey, "vault3r-relay-channel") → hex.
/// The relay never sees the pairing key — only the derived channel ID.
/// </summary>
public static string ComputeChannelId(byte[] pairingKey)
{
    using var hmac = new HMACSHA256(pairingKey);
    var hash = hmac.ComputeHash(
        Encoding.UTF8.GetBytes("vault3r-relay-channel")
    );
    return Convert.ToHexString(hash).ToLowerInvariant();
}
Services/DevicePairingService.cs — E2E encryption C#
/// <summary>
/// Encrypts data with a pairing key using AES-256-GCM.
/// Output format: nonce(12 bytes) + auth_tag(16 bytes) + ciphertext
/// </summary>
public static byte[] Encrypt(byte[] plaintext, byte[] pairingKey)
{
    var nonce = RandomNumberGenerator.GetBytes(12);
    var tag = new byte[16];
    var cipher = new byte[plaintext.Length];

    using var aes = new AesGcm(pairingKey, 16);
    aes.Encrypt(nonce, plaintext, cipher, tag);

    var result = new byte[12 + 16 + cipher.Length];
    Buffer.BlockCopy(nonce, 0, result, 0, 12);
    Buffer.BlockCopy(tag, 0, result, 12, 16);
    Buffer.BlockCopy(cipher, 0, result, 28, cipher.Length);
    return result;
}
Zero knowledge: The relay server never has access to the pairing key. It only sees a channel ID (HMAC-derived, irreversible) and opaque encrypted blobs. Even if the relay were compromised, the attacker could not decrypt any data without the 256-bit key that exists only on your paired devices.

📲Pairing Protocol

Each device pairing is isolated — every pair gets its own 256-bit key and derived channel. Pairing keys are exchanged via QR code using a custom URI scheme. The protocol supports multiple simultaneous pairings.

Services/DevicePairingService.cs — pairing model C#
/// <summary>
/// Model for a single paired device.
/// Each pairing has its own isolated 256-bit key and derived channel.
/// </summary>
public class PairedDevice
{
    [JsonPropertyName("id")]
    public string Id { get; set; } = "";

    [JsonPropertyName("device_name")]
    public string DeviceName { get; set; } = "";

    [JsonPropertyName("pairing_key")]
    public string PairingKeyBase64 { get; set; } = "";

    [JsonPropertyName("channel_id")]
    public string ChannelId { get; set; } = "";

    [JsonPropertyName("paired_at")]
    public string PairedAt { get; set; } = "";
}
Services/DevicePairingService.cs — URI format C#
/// <summary>
/// Builds the pairing URI embedded in the QR code.
/// Format: vault3r-pair://KEY_BASE64?device=DEVICE_NAME
/// </summary>
public static string GetPairingUri(string base64Key)
{
    var deviceName = Uri.EscapeDataString(GetLocalDeviceName());
    var keyEncoded = Uri.EscapeDataString(base64Key);
    return $"vault3r-pair://{keyEncoded}?device={deviceName}";
}

/// <summary>
/// Generates a new 256-bit pairing key using CSPRNG.
/// Key is not saved until the pairing is confirmed by both devices.
/// </summary>
public static string GenerateKeyBase64()
{
    var key = RandomNumberGenerator.GetBytes(32);
    return Convert.ToBase64String(key);
}
Pairing flow: Windows generates a 256-bit key → encodes it as a vault3r-pair:// URI → displays QR code → Android scans and imports the key → both devices derive the same channel ID via HMAC-SHA256 → pairing confirmation is exchanged through the relay (E2E encrypted) → both sides save the pairing only after mutual confirmation.