Skip to content

Security

BlockVault implements defense-in-depth security with multiple layers protecting sensitive data — mnemonics, passwords, and private keys never leave the device.


Architecture Overview

User Password

PBKDF2 (600 000 iterations)

AES-256-GCM Key Derivation

Hardware-Backed Storage (Android Keystore / iOS Keychain)

Device Security Module (TEE / Secure Enclave)

1. Mnemonic Encryption (AES-256-GCM)

Every seed phrase is encrypted before it touches any storage:

ParameterValue
AlgorithmAES-256-GCM (Galois/Counter Mode)
IV128-bit random per encryption
Salt256-bit random per encryption
Auth Tag128-bit (tamper detection)
Key DerivationPBKDF2 — 600 000 iterations (OWASP 2023)

Encryption flow

plaintext mnemonic
    → PBKDF2(password, random-salt, 600k) → 256-bit key
    → AES-256-GCM(key, random-iv) → ciphertext + authTag
    → JSON { version, iv, salt, authTag, encryptedSeed }

The PBKDF2 key derivation runs inside a Web Worker so the UI thread never blocks.

Stored format

json
{
  "version": 2,
  "iv": "hex",
  "salt": "hex",
  "authTag": "hex",
  "encryptedSeed": "hex"
}

2. Hardware-Backed Secure Storage

The encrypted seed JSON is stored through platform-specific hardware security:

Android

  • Backend: Android Keystore (Trusted Execution Environment / StrongBox)
  • Encryption: AES-256-GCM at hardware level
  • Guarantee: Keys never leave the TEE

iOS

  • Backend: iOS Keychain + Secure Enclave
  • Encryption: Hardware-bound AES
  • Guarantee: Not included in device backups

This means data is encrypted twice:

  1. App layer — PBKDF2 + AES-256-GCM (controlled by user password)
  2. Hardware layer — Android Keystore / iOS Keychain AES-GCM (controlled by OS)

3. Password Protection

Hashing

User passwords are hashed with SHA-256 and stored in SecureStorage as "passhash". The hash is hardware-encrypted on mobile and never sent over the network.

Session caching

The plaintext password is held only in memory for the active session:

  • Stored in a Pinia reactive ref (SessionStore)
  • Cleared immediately when the app goes to background
  • No timer — driven by app lifecycle events (appStateChange)
App active   → password in memory (for signing operations)
App paused   → password cleared instantly
App resumed  → user must re-authenticate

4. Biometric Authentication

BlockVault supports platform biometrics as a convenience layer:

PlatformMethods
iOSTouch ID, Face ID
AndroidFingerprint, Face Authentication

How it works

  1. Enrollment — After password verification, credentials are stored in the OS credential store via NativeBiometric.setCredentials.
  2. Authentication — On next unlock, the OS prompts biometric verification (maxAttempts: 3). On success, the password is retrieved from the OS credential store.
  3. Fallback — If biometric fails, the user enters their password manually.

Biometric data itself is never seen by BlockVault — the OS handles matching. BlockVault only receives a success/failure signal and, on success, retrieves the stored password.


5. App Attest (iOS Device Integrity)

On iOS, BlockVault uses App Attest to cryptographically prove:

  • The app binary is genuine (not modified or re-signed)
  • It runs on a real Apple device (not an emulator or jailbroken environment)

This is implemented via a custom Capacitor plugin (capacitor-app-attest) that interfaces with Apple's DeviceCheck framework.


6. Private Keys — Never Stored

Private keys are derived on demand from the encrypted mnemonic and held only for the duration of the signing operation:

User enters password
    → Decrypt mnemonic (AES-256-GCM)
    → Derive private key (BIP32 path)
    → Sign transaction
    → Discard key from memory

Private keys are never persisted to disk, database, or any storage.


Summary

LayerProtection
Mnemonic at restAES-256-GCM + PBKDF2 (600k iterations)
Storage backendAndroid Keystore TEE / iOS Secure Enclave
Session passwordIn-memory only, cleared on background
Biometric unlockOS credential store, 3-attempt limit
Device integrityApp Attest (iOS)
Private keysDerived on demand, never stored
Key derivationWeb Worker (non-blocking)

BlockVault Documentation