Skip to main content

Encryption Features

Trezor Suite implements platform-specific encryption to protect sensitive user data stored on the device, ensuring privacy and security across all platforms.

Overview

Suite encrypts sensitive data at rest:

Local Storage

Encrypted persistent storage for Suite data

Platform Native

Uses OS-specific encryption APIs

Key Management

Secure key derivation and storage

Zero Knowledge

Trezor cannot access your encrypted data

What Gets Encrypted

Sensitive data protected by encryption:

User Data

  • Account labels: Custom names for accounts
  • Transaction labels: Custom transaction notes
  • Address labels: Labeled receiving addresses
  • XPUB metadata: Extended public key information

Application State

  • Settings: User preferences and configuration
  • Remembered wallets: Device pairing information
  • Application flags: Feature flags and state

Privacy Data

  • CoinJoin history: Privacy transaction records
  • Custom backends: Private server configurations
  • Analytics preferences: Tracking opt-in/opt-out status
Private keys are NEVER stored in Suite. They remain on the Trezor device at all times.

Platform-Specific Implementation

Each platform uses native encryption:

Electron Encryption

Uses safeStorage API:
// Location: suite/platform-encryption-electron/

import { safeStorage } from 'electron';

const encryptData = (data: string): Buffer => {
  if (!safeStorage.isEncryptionAvailable()) {
    throw new Error('Encryption not available');
  }
  
  return safeStorage.encryptString(data);
};

const decryptData = (encrypted: Buffer): string => {
  return safeStorage.decryptString(encrypted);
};
Platform Details:
  • Windows: DPAPI (Data Protection API)
  • macOS: Keychain Services
  • Linux: Secret Service API / libsecret

Encryption Architecture

Common Interface

All platforms implement standard interface:
// Location: suite-common/platform-encryption/

export interface PlatformEncryption {
  // Check if encryption is available
  isAvailable(): Promise<boolean>;
  
  // Encrypt data
  encrypt(data: string): Promise<Buffer | ArrayBuffer>;
  
  // Decrypt data
  decrypt(encrypted: Buffer | ArrayBuffer): Promise<string>;
  
  // Check if encryption key exists
  hasKey(): Promise<boolean>;
  
  // Initialize encryption (e.g., create key)
  initialize(): Promise<void>;
}

Key Derivation

Secure key generation:
1

Platform Key

Generate or retrieve platform-specific encryption key
2

User Authentication

Require user authentication (biometric, password, hardware key)
3

Key Derivation

Derive application key using PBKDF2 or similar
4

Secure Storage

Store in platform keystore/keychain

Storage Integration

Redux Persistence

Encrypted Redux state:
import { createEncryptedStorage } from '@suite-common/storage';
import { platformEncryption } from '@suite-native/platform-encryption';

const storage = createEncryptedStorage({
  encryption: platformEncryption,
  key: 'suite-state',
});

const persistConfig = {
  key: 'root',
  storage,
  whitelist: ['wallet', 'suite', 'metadata'],
};

IndexedDB Encryption

For web platform:
import { openDB } from 'idb';
import { platformEncryption } from '@suite/platform-encryption';

const db = await openDB('suite', 1, {
  upgrade(db) {
    db.createObjectStore('encrypted-data');
  },
});

// Store encrypted data
const storeEncrypted = async (key: string, data: any) => {
  const encrypted = await platformEncryption.encrypt(
    JSON.stringify(data)
  );
  
  await db.put('encrypted-data', encrypted, key);
};

// Retrieve and decrypt
const getDecrypted = async (key: string) => {
  const encrypted = await db.get('encrypted-data', key);
  
  if (!encrypted) return null;
  
  const decrypted = await platformEncryption.decrypt(encrypted);
  return JSON.parse(decrypted);
};

Metadata Encryption

Cloud-synced metadata with encryption:

End-to-End Encryption

// User's metadata encrypted before upload
const encryptMetadata = async (metadata: Metadata) => {
  // Derive key from master key + password
  const key = await deriveMetadataKey(
    masterKey,
    userPassword
  );
  
  // Encrypt with AES-256-GCM
  const encrypted = await crypto.subtle.encrypt(
    { name: 'AES-GCM', iv: randomIV() },
    key,
    JSON.stringify(metadata)
  );
  
  // Upload encrypted blob
  await uploadToCloud(encrypted);
};
Metadata encryption is separate from local storage encryption. Cloud metadata uses user-provided password, never stored by Trezor.

Key Management

Key Lifecycle

First time setup:
  1. Check if platform encryption available
  2. Generate master encryption key
  3. Store in platform keystore
  4. Derive application-specific keys
Platform-specific storage:
  • Desktop: OS keyring (DPAPI, Keychain, Secret Service)
  • Web: WebAuthn credential
  • Mobile: Platform keystore (iOS/Android)
Never stored in plaintext or application storage.
Accessing keys:
  • Requires user authentication
  • Biometric or password
  • Limited to application scope
  • Automatic on some platforms
Periodic key updates:
  • Generate new key
  • Re-encrypt all data
  • Replace old key
  • Secure deletion of old key

Key Backup

Encryption keys are NOT backed up. If you:
  • Reinstall OS
  • Clear application data
  • Lose device
You will lose access to encrypted data. However, your Bitcoin/crypto remains safe on Trezor device.

Security Considerations

Threat Model

Protection against:

Physical Access

Attacker with physical device access cannot read encrypted data

Malware

Malware without system privileges cannot decrypt data

Cloud Backup

Cloud backups don’t expose sensitive data

Data Export

Exported application data is encrypted

Limitations

What encryption doesn’t protect:
  • Runtime memory: Data decrypted in memory while Suite running
  • Screen capture: Displayed data can be captured
  • Privileged malware: System-level malware can access keys
  • User authentication: Weak platform authentication undermines encryption

Error Handling

Encryption Failures

Graceful degradation:
const saveData = async (data: any) => {
  try {
    // Try encrypted storage
    const encrypted = await platformEncryption.encrypt(
      JSON.stringify(data)
    );
    await storage.save(encrypted);
  } catch (error) {
    if (error.code === 'ENCRYPTION_UNAVAILABLE') {
      // Warn user
      showWarning('Encryption not available. Data will be stored unencrypted.');
      
      // Fall back to unencrypted storage
      await storage.save(data);
    } else {
      // Handle other errors
      throw error;
    }
  }
};

Decryption Failures

Handle corrupted or inaccessible data:
const loadData = async () => {
  try {
    const encrypted = await storage.load();
    return await platformEncryption.decrypt(encrypted);
  } catch (error) {
    if (error.code === 'DECRYPTION_FAILED') {
      // Data corrupted or key lost
      logger.error('Cannot decrypt data', error);
      
      // Clear corrupted data
      await storage.clear();
      
      // Start fresh
      return null;
    }
    throw error;
  }
};

Performance Impact

Overhead

Encryption adds minimal overhead:
OperationWithout EncryptionWith EncryptionOverhead
Save data5ms8ms+60%
Load data3ms5ms+66%
App startup200ms220ms+10%

Optimization

Batch encrypt/decrypt operations to reduce overhead
Cache decrypted data in memory during session
Decrypt only when data is accessed
Only encrypt truly sensitive data

Testing Encryption

Unit Tests

Test encryption functionality:
import { platformEncryption } from '@suite/platform-encryption';

describe('Platform Encryption', () => {
  it('should encrypt and decrypt data', async () => {
    const data = 'sensitive information';
    
    const encrypted = await platformEncryption.encrypt(data);
    expect(encrypted).not.toEqual(data);
    
    const decrypted = await platformEncryption.decrypt(encrypted);
    expect(decrypted).toEqual(data);
  });
  
  it('should fail on tampered data', async () => {
    const encrypted = await platformEncryption.encrypt('data');
    
    // Tamper with encrypted data
    const tampered = Buffer.from(encrypted);
    tampered[0] ^= 0xFF;
    
    await expect(
      platformEncryption.decrypt(tampered)
    ).rejects.toThrow();
  });
});

Best Practices

For Users

  • Use strong platform authentication
  • Enable biometric protection when available
  • Don’t share device access
  • Keep OS and Suite updated

For Developers

  • Always check encryption availability
  • Handle encryption errors gracefully
  • Never log decrypted sensitive data
  • Clear sensitive data from memory
  • Use constant-time comparison

Implementation Files

// Platform encryption packages
suite/platform-encryption-electron/     // Desktop
suite/platform-encryption-webauthn/     // Web
suite-native/platform-encryption-native/ // Mobile

// Common interface
suite-common/platform-encryption/
  src/
    types.ts           // TypeScript interfaces
    utils.ts           // Shared utilities

// Storage integration
suite-common/suite-storage/
  src/
    encryptedStorage.ts // Encrypted storage wrapper

Build docs developers (and LLMs) love