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.
Each platform uses native encryption:
Desktop (Electron)
Web (WebAuthn)
Mobile (Native)
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
WebAuthn Encryption Uses WebCrypto with WebAuthn: // Location: suite/platform-encryption-webauthn/
import { getKeyFromWebAuthn } from './webauthn' ;
const encryptData = async ( data : string ) : Promise < ArrayBuffer > => {
// Derive key from WebAuthn credential
const key = await getKeyFromWebAuthn ();
// Generate IV
const iv = crypto . getRandomValues ( new Uint8Array ( 12 ));
// Encrypt with AES-GCM
const encrypted = await crypto . subtle . encrypt (
{ name: 'AES-GCM' , iv },
key ,
new TextEncoder (). encode ( data )
);
// Return IV + encrypted data
return concatenate ( iv , new Uint8Array ( encrypted ));
};
Security:
User authentication required for decryption
Biometric or hardware key
Key never leaves browser
React Native Encryption Uses platform keystore: // Location: suite-native/platform-encryption-native/
import { EncryptedStorage } from 'react-native-encrypted-storage' ;
const encryptData = async ( key : string , data : string ) => {
await EncryptedStorage . setItem ( key , data );
};
const decryptData = async ( key : string ) : Promise < string > => {
return await EncryptedStorage . getItem ( key );
};
Platform Details:
iOS : Keychain Services
Android : Keystore System
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:
Platform Key
Generate or retrieve platform-specific encryption key
User Authentication
Require user authentication (biometric, password, hardware key)
Key Derivation
Derive application key using PBKDF2 or similar
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 );
};
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:
Check if platform encryption available
Generate master encryption key
Store in platform keystore
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 ;
}
};
Overhead
Encryption adds minimal overhead:
Operation Without Encryption With Encryption Overhead Save data 5ms 8ms +60% Load data 3ms 5ms +66% App startup 200ms 220ms +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