Version: 2.5.0-PRO | Last Updated: 2026-05-01
This document describes the public APIs available in CrytoTool for developers who want to understand, extend, or integrate with the crypto services.
Important: CrytoTool is 100% client-side. All APIs run in the browser/WebView context. There is no server API.
- Crypto Service
- Backup Crypto Service
- Stream Crypto
- Vault Storage
- Database (IndexedDB)
- Security Utilities
Location: utils/crypto.ts
Central service for all encryption/decryption operations. Uses Web Crypto API and libsodium-wrappers.
Derives the vault master key from Master Password using Argon2id.
const salt = window.crypto.getRandomValues(new Uint8Array(16));
const masterKey: CryptoKey = await cryptoService.deriveMasterKey('MyPassword123!', salt);Parameters:
password: string- The person's master passwordsalt: Uint8Array- 16-byte random salt (stored in localStorage ascrytotool_salt)
Returns: Promise<CryptoKey> - AES-256-GCM CryptoKey (non-extractable)
Argon2id Parameters:
- Memory: 64MB (65536 KB)
- Iterations: 10
- Parallelism: 4 threads
- Hash length: 32 bytes
Encrypts data using the vault key (default) or provided key.
const encrypted: EncryptedData = await cryptoService.encrypt(fileBlob);Parameters:
data: Blob | Uint8Array- Data to encryptkey: CryptoKey(optional) - Defaults tothis.vaultKey
Returns: Promise<EncryptedData>
interface EncryptedData {
ciphertext: Uint8Array;
iv: Uint8Array; // 12 bytes random
salt: Uint8Array; // Empty for default encryption
algorithm: CryptoAlgorithm;
}Decrypts data using vault key or passphrase.
const decrypted: Uint8Array = await cryptoService.decrypt(
encryptedData, iv, vaultKey, 'AES-GCM'
);Parameters:
encryptedData: Uint8Array- Ciphertextiv: Uint8Array- Initialization vectorkey: CryptoKey(optional) - Defaults tothis.vaultKeyalgorithm: CryptoAlgorithm(optional) - Defaults to 'AES-GCM'salt: Uint8Array(optional) - Required for passphrase decryptionpassphrase: string(optional) - For manual decryption
Encrypts a string using Vault Key (for localStorage storage).
const encrypted = await cryptoService.encryptString('my-secret-key-1234');
// Returns: { ciphertext: string (base64), iv: string (base64) }Used for: Encrypting PIN hash, recovery codes, vault keys before localStorage.
Decrypts a string encrypted with encryptString().
const decrypted = await cryptoService.decryptString(
encrypted.ciphertext,
encrypted.iv
);Manual encryption with person-chosen algorithm and passphrase.
const encrypted = await cryptoService.encryptWithPassphrase(
fileData,
'MY-SECRET-KEY',
'XChaCha20-Poly1305'
);Supported Algorithms:
'AES-GCM'- NIST standard, hardware-accelerated'AES-CTR'- With HMAC integrity check'ChaCha20-Poly1305'- Mobile-optimized'XChaCha20-Poly1305'- Extended nonce (192-bit)'Salsa20-Poly1305'- DJB's stream cipher'AES-GCM-Stream'- UsestreamCrypto.encrypt()instead
Location: utils/backupCrypto.ts
Handles encrypted backup creation and restoration.
Generates a 26-character backup key (130 bits entropy).
const key = backupCryptoService.generatePassphrase();
// Returns: "X9F2-KLP0-ABCD-EFGH-IJKL-MNOP-QRST-UVWX"Character set: ABCDEFGHJKLMNPQRSTUVWXYZ23456789 (no ambiguous chars)
Encrypts backup data with PBKDF2-SHA256 + AES-256-GCM.
const backup = await backupCryptoService.encryptBackup(
JSON.stringify(backupData),
passphrase
);
// Returns: Uint8Array in format [16-byte salt][12-byte IV][ciphertext + 16-byte GCM tag]Decrypts a backup file.
const decrypted = await backupCryptoService.decryptBackup(
backupArrayBuffer,
passphrase
);
const backupData = JSON.parse(decrypted);Location: utils/streamCrypto.ts
Processes large files in 4MB chunks to avoid memory issues.
Streaming encryption for large files.
const encrypted = await streamCrypto.encrypt(fileBlob, 'STREAM-KEY');
// Returns: Uint8Array with header + encrypted chunksHeader Format:
interface StreamHeader {
magic: 'CRYTO_STREAM'; // 12 bytes
version: 1; // 4 bytes
algorithm: 'AES-GCM-Stream';
chunkSize: 4194304; // 4MB
totalChunks: number;
originalSize: number;
salt: Uint8Array; // 16 bytes
baseIV: Uint8Array; // 12 bytes
}Decrypts streaming-encrypted files.
const decrypted = await streamCrypto.decrypt(encryptedBuffer, passphrase);
// Returns: Uint8Array of original fileLocation: utils/vaultStorage.ts
Manages encrypted storage of manual encryption keys in localStorage.
Saves all vault key entries (encrypted with Vault Key).
await vaultStorage.saveAll([
{ name: 'My Key', category: 'personal', key: 'ABCD-1234-...' }
]);
// Stored in localStorage as 'crytotool_vault_keys' (encrypted JSON)Retrieves and decrypts vault key entries.
const entries = await vaultStorage.getAll();
// Returns: VaultKeyEntry[] or [] if errorHandles: Legacy plaintext format migration.
Location: utils/db.ts
Wrapper for IndexedDB operations.
Adds encrypted file/folder to vault.
await db.addItem({
id: crypto.randomUUID(),
parentId: null, // root level
type: 'file',
name: 'document.pdf',
fileData: encryptedBlob,
iv: base64IV,
algorithm: 'AES-GCM',
isEncrypted: true,
category: 'doc'
});Exports all data for backup.
const data = await db.exportDatabase();
// Returns: DBItem[] (all items in IndexedDB)Imports data from backup.
await db.importDatabase(backupData.db);Location: utils/security.ts
Hashes and encrypts a 6-digit PIN for localStorage.
const encryptedHash = await hashPin('123456');
// Stored as 'crytotool_vault_pin_hash' (encrypted)Verifies a PIN against stored hash (handles encrypted and legacy formats).
const isValid = await verifyPin('123456', storedHash);
// Returns: booleanCalculates lockout duration after failed unlock attempts.
const seconds = getBackoffTime(3); // Returns: 30
// 3 attempts → 30s, 4 → 60s, 5+ → 300stype CryptoAlgorithm =
| 'AES-GCM'
| 'AES-CTR'
| 'ChaCha20-Poly1305'
| 'XChaCha20-Poly1305'
| 'Salsa20-Poly1305'
| 'AES-GCM-Stream';
interface DBItem {
id: string;
parentId: string | null;
type: 'file' | 'folder' | 'system';
name: string;
size?: string;
date: string;
fileData?: Blob;
iv?: string; // Base64
salt?: string; // Base64
algorithm?: CryptoAlgorithm;
isEncrypted?: boolean;
category?: 'image' | 'video' | 'audio' | 'doc' | 'other';
isTrashed?: boolean;
tags?: Tag[];
customIcon?: string;
}
interface VaultKeyEntry {
name: string;
category: string;
key: string; // The actual encryption key
}- Vault Key is private - Not accessible via
window.cryptoService.vaultKey(closure pattern) - All crypto runs in browser - No server involved
- Use
encryptString/decryptStringfor any localStorage storage - Always handle errors - Crypto operations can fail (e.g., wrong key)
- People-first terminology - Use "people"/"persoane" in all UI text
// 1. Generate key
const key = 'ABCD-1234-EFGH-5678';
// 2. Get file data
const fileData = new Uint8Array(await file.arrayBuffer());
// 3. Encrypt with chosen algorithm
const encrypted = await cryptoService.encryptWithPassphrase(
fileData,
key,
'XChaCha20-Poly1305'
);
// 4. Save to vault
await db.addItem({
id: crypto.randomUUID(),
parentId: null,
type: 'file',
name: file.name,
fileData: new Blob([encrypted.ciphertext]),
iv: btoa(String.fromCharCode(...encrypted.iv)),
salt: btoa(String.fromCharCode(...encrypted.salt)),
algorithm: 'XChaCha20-Poly1305',
isEncrypted: true
});
// 5. Optionally save key to vault storage
await vaultStorage.saveAll([...existing, { name: 'My File Key', category: 'docs', key }]);// 1. Get item from DB
const item = await db.getItem(itemId);
// 2. Decrypt
const decrypted = await cryptoService.decrypt(
new Uint8Array(await item.fileData.arrayBuffer()),
base64ToArrayBuffer(item.iv),
undefined,
item.algorithm,
base64ToArrayBuffer(item.salt),
'ABCD-1234-EFGH-5678' // passphrase
);
// 3. Create download
const blob = new Blob([decrypted]);
const url = URL.createObjectURL(blob);
// ... trigger download