@everabyte/evb-sdk-typescript
v1.0.4
Published
Everabyte SDK - Zero-Knowledge E2EE Cryptographic Library for TypeScript/JavaScript/Node.js
Downloads
309
Maintainers
Readme
@everabyte/evb-sdk-typescript
Zero-Knowledge End-to-End Encryption (E2EE) SDK for TypeScript and JavaScript
📋 Overview
EvbSDK TypeScript is a production-ready cryptographic library that provides secure file storage with zero-knowledge architecture. Your files are encrypted client-side before they ever reach the server, ensuring complete privacy and security.
🎯 Key Features
- ✅ Zero-Knowledge E2EE - Server never sees plaintext or private keys
- ✅ HPKE RFC 9180 - Hybrid Public Key Encryption (X25519-HKDF-SHA256)
- ✅ AES-256-GCM - Industry-standard symmetric encryption with authentication
- ✅ Chunked Encryption - Handle files of any size (1MB chunks for memory efficiency)
- ✅ Progress Tracking - Built-in progress callbacks for long operations
- ✅ Cross-Platform - Works in Browser, Node.js, React Native, and TypeScript
- ✅ TypeScript Support - Full type definitions included
- ✅ 100% Test Coverage - Production-ready with comprehensive tests
🌐 Platform Support
| Platform | Status | Notes | |----------|--------|-------| | Browser | ✅ Fully Supported | Chrome 90+, Firefox 88+, Safari 15+, Edge 90+ | | Node.js | ✅ Fully Supported | Node.js 16.0.0+ (uses crypto module) | | TypeScript | ✅ Fully Supported | TypeScript 5.0+ with full type definitions | | React Native | ⚠️ Planned | Web Crypto API polyfill required | | Electron | ✅ Fully Supported | Uses browser Web Crypto API |
⚠️ Important: This SDK automatically detects the environment and uses the appropriate crypto implementation:
- Browser: Web Crypto API (native)
- Node.js: crypto module (webcrypto)
📦 Prerequisites
Before installing the SDK, ensure you have:
- Node.js 16.0.0 or higher
- npm 7.0.0 or higher (or yarn 1.22+ / pnpm 6.0+)
- A modern web browser with Web Crypto API support
- TypeScript 5.0+ (if using TypeScript)
Development Environment
For development:
# Check Node.js version
node --version # Should be v16.0.0 or higher
# Check npm version
npm --version # Should be v7.0.0 or higher🚀 Installation
Install from npm Public Registry
Install the package directly from npm:
npm install @everabyte/evb-sdk-typescriptOr with yarn:
yarn add @everabyte/evb-sdk-typescriptOr with pnpm:
pnpm add @everabyte/evb-sdk-typescriptInstall from Local File (Development)
For local development:
npm install /path/to/evb-sdk/typescriptVerify Installation
npm list @everabyte/evb-sdk-typescript📖 Usage
Platform-Specific Usage
Node.js Usage
The SDK works seamlessly in Node.js environments (16.0.0+). It automatically detects the environment and uses the Node.js crypto module.
import { E2EECore } from '@everabyte/evb-sdk-typescript/e2ee';
import { readFileSync, writeFileSync } from 'fs';
import { Buffer } from 'buffer';
async function encryptFileNodeJS(filePath: string) {
const e2ee = new E2EECore();
// Read file as Buffer
const fileBuffer = readFileSync(filePath);
// Encrypt file
const result = await e2ee.prepareUpload({
file: fileBuffer, // Pass Buffer directly
chunkSize: 1024 * 1024,
onProgress: (stage, progress) => {
console.log(`[${stage}] ${progress}%`);
},
});
if (result.success) {
// Get encrypted data as Buffer
const encryptedBuffer = Buffer.from(
await result.encryptedFile.arrayBuffer()
);
// Save encrypted file
writeFileSync('encrypted.bin', encryptedBuffer);
console.log('File encrypted successfully!');
console.log('AES Key (base64):', result.aesKeyBase64);
return result.aesKeyBase64;
}
}
async function decryptFileNodeJS(
encryptedFilePath: string,
aesKeyBase64: string
) {
const e2ee = new E2EECore();
// Read encrypted file
const encryptedBuffer = readFileSync(encryptedFilePath);
const encryptedBlob = new Blob([encryptedBuffer]);
// Decrypt file
const result = await e2ee.decryptDownload({
encryptedData: await encryptedBlob.arrayBuffer(),
aesKeyBase64: aesKeyBase64, // Direct AES key
onProgress: (progress) => {
console.log(`Decrypting: ${progress}%`);
},
});
if (result.success) {
// Get decrypted data as Buffer
const decryptedBuffer = Buffer.from(
await result.decryptedFile.arrayBuffer()
);
// Save decrypted file
writeFileSync('decrypted.txt', decryptedBuffer);
console.log('File decrypted successfully!');
}
}
// Usage
encryptFileNodeJS('document.txt').catch(console.error);
decryptFileNodeJS('encrypted.bin', 'your-aes-key-base64').catch(console.error);Frontend TypeScript Usage
The SDK is fully compatible with TypeScript frontends (React, Vue, Angular, etc.).
import { E2EECore } from '@everabyte/evb-sdk-typescript/e2ee';
interface UploadResult {
success: boolean;
fileId?: string;
error?: string;
}
async function uploadFile(file: File): Promise<UploadResult> {
const e2ee = new E2EECore();
try {
// Encrypt file with type safety
const result = await e2ee.prepareUpload({
file: file,
chunkSize: 1024 * 1024,
onProgress: (stage: string, progress: number) => {
console.log(`[${stage}] ${progress}%`);
},
});
if (!result.success) {
return { success: false, error: result.error };
}
// Upload to server
const formData = new FormData();
formData.append('file', result.encryptedFile, file.name);
formData.append('aesKeyBase64', result.aesKeyBase64);
const response = await fetch('/api/files/upload', {
method: 'POST',
body: formData,
});
if (!response.ok) {
throw new Error('Upload failed');
}
const data = await response.json();
return { success: true, fileId: data.fileId };
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
}HTTP Client Integration
Using Fetch API
The SDK works perfectly with the native Fetch API available in modern browsers and Node.js 18+.
import { E2EECore } from '@everabyte/evb-sdk-typescript/e2ee';
// Upload with Fetch
async function uploadWithFetch(file: File) {
const e2ee = new E2EECore();
// Encrypt file
const result = await e2ee.prepareUpload({
file: file,
chunkSize: 1024 * 1024,
onProgress: (stage, progress) => {
console.log(`${stage}: ${progress}%`);
},
});
if (!result.success) {
throw new Error(result.error);
}
// Upload with Fetch
const formData = new FormData();
formData.append('file', result.encryptedFile, file.name);
formData.append('aesKeyBase64', result.aesKeyBase64);
formData.append('originalSize', file.size.toString());
formData.append('mimeType', file.type);
const response = await fetch('/api/files/upload', {
method: 'POST',
body: formData,
// Note: Don't set Content-Type header when using FormData
// Fetch will set it automatically with the correct boundary
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data.fileId;
}
// Download with Fetch
async function downloadWithFetch(fileId: string) {
const e2ee = new E2EECore();
// Download encrypted file
const response = await fetch(`/api/files/download/${fileId}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const encryptedData = await response.arrayBuffer();
// Get HPKE metadata from headers
const encapsulatedKey = response.headers.get('X-HPKE-Encapsulated-Key') || '';
const ciphertext = response.headers.get('X-HPKE-Ciphertext') || '';
// Decrypt file
const result = await e2ee.decryptDownload({
encryptedData: encryptedData,
encapsulatedKey: encapsulatedKey,
ciphertext: ciphertext,
onProgress: (progress) => {
console.log(`Decrypting: ${progress}%`);
},
});
if (!result.success) {
throw new Error(result.error);
}
return result.decryptedFile;
}
// Usage in browser
const fileInput = document.querySelector('input[type="file"]');
fileInput?.addEventListener('change', async (e) => {
const file = (e.target as HTMLInputElement).files?.[0];
if (!file) return;
try {
const fileId = await uploadWithFetch(file);
console.log('File uploaded:', fileId);
const decryptedBlob = await downloadWithFetch(fileId);
const url = URL.createObjectURL(decryptedBlob);
const link = document.createElement('a');
link.href = url;
link.download = file.name;
link.click();
URL.revokeObjectURL(url);
} catch (error) {
console.error('Error:', error);
}
});Using Axios
For better error handling, request cancellation, and interceptors, you can use Axios.
import axios, { AxiosInstance, AxiosProgressEvent } from 'axios';
import { E2EECore } from '@everabyte/evb-sdk-typescript/e2ee';
// Create Axios instance with configuration
const apiClient: AxiosInstance = axios.create({
baseURL: 'https://api.everabyte.io/api',
timeout: 30000,
headers: {
'Content-Type': 'application/json',
},
});
// Upload with Axios
async function uploadWithAxios(
file: File,
onProgress?: (progress: number) => void
): Promise<string> {
const e2ee = new E2EECore();
// Encrypt file
const result = await e2ee.prepareUpload({
file: file,
chunkSize: 1024 * 1024,
onProgress: (stage, progress) => {
console.log(`${stage}: ${progress}%`);
},
});
if (!result.success) {
throw new Error(result.error);
}
// Upload with Axios
const formData = new FormData();
formData.append('file', result.encryptedFile, file.name);
formData.append('aesKeyBase64', result.aesKeyBase64);
formData.append('originalSize', file.size.toString());
formData.append('mimeType', file.type);
const response = await apiClient.post('/files/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: (progressEvent: AxiosProgressEvent) => {
if (progressEvent.total && onProgress) {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
onProgress(percentCompleted);
}
},
});
return response.data.fileId;
}
// Download with Axios
async function downloadWithAxios(
fileId: string,
onProgress?: (progress: number) => void
): Promise<Blob> {
const e2ee = new E2EECore();
// Download encrypted file
const response = await apiClient.get<ArrayBuffer>(`/files/download/${fileId}`, {
responseType: 'arraybuffer',
onDownloadProgress: (progressEvent: AxiosProgressEvent) => {
if (progressEvent.total && onProgress) {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
onProgress(percentCompleted);
}
},
});
const encryptedData = response.data;
// Get HPKE metadata from headers
const encapsulatedKey = response.headers['x-hpke-encapsulated-key'] || '';
const ciphertext = response.headers['x-hpke-ciphertext'] || '';
// Decrypt file
const result = await e2ee.decryptDownload({
encryptedData: encryptedData,
encapsulatedKey: encapsulatedKey,
ciphertext: ciphertext,
onProgress: (progress) => {
console.log(`Decrypting: ${progress}%`);
},
});
if (!result.success) {
throw new Error(result.error);
}
return result.decryptedFile;
}
// Usage example with progress tracking
async function uploadExample() {
const file = /* Get file from input */;
try {
console.log('Starting upload...');
const fileId = await uploadWithAxios(file, (progress) => {
console.log(`Upload progress: ${progress}%`);
});
console.log('Upload complete! File ID:', fileId);
} catch (error) {
console.error('Upload failed:', error);
}
}
// Usage example with error handling
async function downloadExample(fileId: string) {
try {
console.log('Starting download...');
const decryptedBlob = await downloadWithAxios(fileId, (progress) => {
console.log(`Download progress: ${progress}%`);
});
console.log('Download complete!');
// Save file
const url = URL.createObjectURL(decryptedBlob);
const link = document.createElement('a');
link.href = url;
link.download = `decrypted-${fileId}`;
link.click();
URL.revokeObjectURL(url);
} catch (error) {
if (axios.isAxiosError(error)) {
console.error('Download failed:', error.response?.data || error.message);
} else {
console.error('Download failed:', error);
}
}
}Advanced Axios Configuration
import axios, { AxiosInstance } from 'axios';
// Create Axios instance with interceptors
const createApiClient = (baseURL: string): AxiosInstance => {
const client = axios.create({
baseURL,
timeout: 60000, // 60 seconds
});
// Request interceptor
client.interceptors.request.use(
(config) => {
// Add auth token if available
const token = localStorage.getItem('authToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// Response interceptor
client.interceptors.response.use(
(response) => response,
(error) => {
// Handle common errors
if (error.response?.status === 401) {
// Redirect to login
window.location.href = '/login';
}
return Promise.reject(error);
}
);
return client;
};
// Usage
const api = createApiClient('https://api.everabyte.io/api');
async function uploadWithAuth(file: File) {
const e2ee = new E2EECore();
const result = await e2ee.prepareUpload({ file });
if (!result.success) {
throw new Error(result.error);
}
const formData = new FormData();
formData.append('file', result.encryptedFile, file.name);
formData.append('aesKeyBase64', result.aesKeyBase64);
const response = await api.post('/files/upload', formData);
return response.data.fileId;
}Quick Start
Step 1: Import and Configure
import { configureSDK } from '@everabyte/evb-sdk-typescript/config';
import { E2EECore } from '@everabyte/evb-sdk-typescript/e2ee';
// Configure SDK (optional)
configureSDK({
apiBaseUrl: 'https://api.everabyte.io/api',
chunkSize: 1024 * 1024, // 1MB chunks
debug: false,
});Step 2: Encrypt and Upload a File
const e2ee = new E2EECore();
// Encrypt file client-side (zero-knowledge)
const result = await e2ee.prepareUpload({
file: myFile,
chunkSize: 1024 * 1024, // 1MB chunks
onProgress: (stage, progress) => {
console.log(`${stage}: ${progress}%`);
},
});
if (result.success) {
// Upload encrypted file to server
const formData = new FormData();
formData.append('file', result.encryptedFile, myFile.name);
formData.append('aesKeyBase64', result.aesKeyBase64);
const response = await fetch('/api/files/upload', {
method: 'POST',
body: formData,
});
console.log('File uploaded successfully!');
} else {
console.error('Encryption failed:', result.error);
}Step 3: Download and Decrypt a File
// Download encrypted file
const response = await fetch('/api/files/download/FILE_ID');
const encryptedData = await response.arrayBuffer();
// Get HPKE metadata from response headers
const encapsulatedKey = response.headers.get('X-HPKE-Encapsulated-Key') || '';
const ciphertext = response.headers.get('X-HPKE-Ciphertext') || '';
// Decrypt file
const result = await e2ee.decryptDownload({
encryptedData,
encapsulatedKey,
ciphertext,
onProgress: (progress) => {
console.log(`Decrypting: ${progress}%`);
},
});
if (result.success) {
// Save decrypted file
const blob = result.decryptedFile;
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'decrypted-file.txt';
link.click();
URL.revokeObjectURL(url);
}Complete Usage Examples
File Upload with Progress Tracking (Browser)
import { E2EECore } from '@everabyte/evb-sdk-typescript/e2ee';
async function uploadFile(file: File) {
const e2ee = new E2EECore();
// Encrypt file client-side
const result = await e2ee.prepareUpload({
file: file,
chunkSize: 1024 * 1024, // 1MB chunks
onProgress: (stage, progress) => {
console.log(`[${stage}] ${progress}%`);
// Update UI progress bar
updateProgressBar(stage, progress);
},
});
if (!result.success) {
throw new Error(result.error);
}
// Upload encrypted file to server
const formData = new FormData();
formData.append('file', result.encryptedFile, file.name);
formData.append('aesKeyBase64', result.aesKeyBase64);
formData.append('originalSize', file.size.toString());
formData.append('mimeType', file.type);
const response = await fetch('/api/files/upload', {
method: 'POST',
body: formData,
});
if (!response.ok) {
throw new Error('Upload failed');
}
const data = await response.json();
return data.fileId;
}
// Usage
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', async (e) => {
const file = e.target.files[0];
try {
const fileId = await uploadFile(file);
console.log('File uploaded:', fileId);
} catch (error) {
console.error('Error:', error);
}
});File Download with Decryption
import { E2EECore } from '@everabyte/evb-sdk-typescript/e2ee';
async function downloadFile(fileId: string) {
const e2ee = new E2EECore();
// Download encrypted file
const response = await fetch(`/api/files/download/${fileId}`);
if (!response.ok) {
throw new Error('Download failed');
}
const encryptedData = await response.arrayBuffer();
// Get HPKE metadata from headers
const encapsulatedKey = response.headers.get('X-HPKE-Encapsulated-Key') || '';
const ciphertext = response.headers.get('X-HPKE-Ciphertext') || '';
// Decrypt file
const result = await e2ee.decryptDownload({
encryptedData: encryptedData,
encapsulatedKey: encapsulatedKey,
ciphertext: ciphertext,
onProgress: (progress) => {
console.log(`Decrypting: ${progress}%`);
},
});
if (!result.success) {
throw new Error(result.error);
}
// Save file
const blob = result.decryptedFile;
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'decrypted-file.txt';
link.click();
URL.revokeObjectURL(url);
}
// Usage
downloadFile('file-id-123').catch(console.error);HPKE Key Management
import { HPKEKeyManager } from '@everabyte/evb-sdk-typescript/e2ee';
async function setupUserKeys(userId: string) {
const keyManager = HPKEKeyManager.getInstance();
// Check if user already has keys
const existingPublicKey = keyManager.getPublicKey(userId);
if (existingPublicKey) {
console.log('User already has keys');
return existingPublicKey;
}
// Generate new key pair
const keyPair = await keyManager.generateKeyPair();
// Store keys (in memory or secure storage)
keyManager.storeKeyPair(userId, keyPair);
// Upload public key to server
await fetch('/api/users/keys', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
publicKey: keyPair.publicKey,
}),
});
console.log('Keys generated and stored');
return keyPair.publicKey;
}
// Usage
setupUserKeys('user-123').then(publicKey => {
console.log('Public key:', publicKey);
});Sharing Files with Other Users
import { E2EECore } from '@everabyte/evb-sdk-typescript/e2ee';
async function shareFile(file: File, recipientPublicKey: string) {
const e2ee = new E2EECore();
// Step 1: Encrypt file
const encryptResult = await e2ee.prepareUpload({
file: file,
chunkSize: 1024 * 1024,
});
if (!encryptResult.success) {
throw new Error(encryptResult.error);
}
// Step 2: Encapsulate AES key for recipient
const hpkeResult = await e2ee.encapsulateAESKey(
recipientPublicKey,
encryptResult.aesKeyBase64
);
// Step 3: Upload with recipient-specific metadata
const formData = new FormData();
formData.append('file', encryptResult.encryptedFile, file.name);
formData.append('encapsulatedKey', hpkeResult.encapsulatedKey);
formData.append('ciphertext', hpkeResult.ciphertext);
const response = await fetch('/api/files/share', {
method: 'POST',
body: formData,
});
return response.json();
}
// Usage
shareFile(myFile, 'recipient-public-key-base64')
.then(result => console.log('File shared:', result));React Integration Example
import React, { useState } from 'react';
import { E2EECore } from '@everabyte/evb-sdk-typescript/e2ee';
function FileUpload() {
const [uploading, setUploading] = useState(false);
const [progress, setProgress] = useState(0);
const [status, setStatus] = useState('');
const handleFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (!file) return;
setUploading(true);
setProgress(0);
setStatus('Encrypting...');
try {
const e2ee = new E2EECore();
// Encrypt file
const result = await e2ee.prepareUpload({
file,
onProgress: (stage, currentProgress) => {
setStatus(stage);
setProgress(currentProgress);
},
});
if (!result.success) {
throw new Error(result.error);
}
setStatus('Uploading...');
// Upload to server
const formData = new FormData();
formData.append('file', result.encryptedFile);
formData.append('aesKeyBase64', result.aesKeyBase64);
const response = await fetch('/api/files/upload', {
method: 'POST',
body: formData,
});
if (!response.ok) {
throw new Error('Upload failed');
}
setStatus('Complete!');
setProgress(100);
} catch (error) {
setStatus(`Error: ${error.message}`);
} finally {
setUploading(false);
}
};
return (
<div>
<input
type="file"
onChange={handleFileUpload}
disabled={uploading}
/>
{uploading && (
<div>
<p>{status}</p>
<progress value={progress} max={100} />
<p>{progress}%</p>
</div>
)}
</div>
);
}
export default FileUpload;Vue.js Integration Example
<template>
<div>
<input
type="file"
@change="handleFileUpload"
:disabled="uploading"
/>
<div v-if="uploading">
<p>{{ status }}</p>
<progress :value="progress" max="100"></progress>
<p>{{ progress }}%</p>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { E2EECore } from '@everabyte/evb-sdk-typescript/e2ee';
const uploading = ref(false);
const progress = ref(0);
const status = ref('');
const handleFileUpload = async (e: Event) => {
const target = e.target as HTMLInputElement;
const file = target.files?.[0];
if (!file) return;
uploading.value = true;
progress.value = 0;
status.value = 'Encrypting...';
try {
const e2ee = new E2EECore();
const result = await e2ee.prepareUpload({
file,
onProgress: (stage, currentProgress) => {
status.value = stage;
progress.value = currentProgress;
},
});
if (!result.success) {
throw new Error(result.error);
}
status.value = 'Uploading...';
const formData = new FormData();
formData.append('file', result.encryptedFile);
formData.append('aesKeyBase64', result.aesKeyBase64);
const response = await fetch('/api/files/upload', {
method: 'POST',
body: formData,
});
if (!response.ok) {
throw new Error('Upload failed');
}
status.value = 'Complete!';
progress.value = 100;
} catch (error) {
status.value = `Error: ${error.message}`;
} finally {
uploading.value = false;
}
};
</script>🔒 Security Architecture
Zero-Knowledge Flow
┌─────────────────────────────────────────────────────────────┐
│ CLIENT │
│ (Browser) │
│ │
│ 1. Generate AES-256 key │
│ 2. Encrypt file with AES-256-GCM (chunked) │
│ 3. Encapsulate AES key with HPKE (X25519) │
│ 4. Send encrypted file + encapsulated key │
└────────────────────────┬────────────────────────────────────┘
│
│ Encrypted Data Only
│ (No plaintext, no private keys)
▼
┌─────────────────────────────────────────────────────────────┐
│ SERVER │
│ (Ephemeral) │
│ │
│ ✓ Receives encrypted file │
│ ✓ Receives encapsulated AES key │
│ ✗ NEVER sees plaintext │
│ ✗ NEVER sees private keys │
│ ✗ CANNOT decrypt files │
└────────────────────────┬────────────────────────────────────┘
│
│ Encrypted Data Only
▼
┌─────────────────────────────────────────────────────────────┐
│ STORAGE │
│ (S3, Database, etc) │
│ │
│ ✓ Stores encrypted files │
│ ✓ Stores encapsulated keys │
│ ✗ NO plaintext data │
└─────────────────────────────────────────────────────────────┘Cryptographic Specifications
| Component | Algorithm | Key Size | Security Level | |-----------|-----------|----------|----------------| | HPKE KEM | X25519 (ECDH) | 256-bit | 128-bit security | | HPKE KDF | HKDF-SHA256 | 256-bit | 256-bit security | | HPKE AEAD | AES-256-GCM | 256-bit | 256-bit security | | File Encryption | AES-256-GCM | 256-bit | 256-bit security | | Nonce | Random | 96-bit | - |
Security Guarantees
✅ Zero-Knowledge: Server never sees plaintext files or private keys
✅ Forward Secrecy: Compromised keys don't reveal past communications
✅ Authenticated Encryption: AES-GCM provides integrity and authenticity
✅ Ephemeral Keys: Each file gets a unique AES-256 key
✅ RFC 9180 Compliant: HPKE implementation follows IETF standard
🔧 API Reference
E2EECore
Main class for E2EE operations.
prepareUpload(options)
Encrypt a file for zero-knowledge upload.
Parameters:
{
file: File; // File to encrypt
chunkSize?: number; // Chunk size in bytes (default: 1MB)
onProgress?: (stage: 'encrypting' | 'uploading', progress: number) => void;
}Returns:
{
encryptedFile: Blob; // Encrypted file data
aesKeyBase64: string; // AES-256 key (base64 encoded)
success: boolean; // Operation status
error?: string; // Error message if failed
}decryptDownload(options)
Decrypt a downloaded file.
Parameters:
{
encryptedData: ArrayBuffer | Blob; // Encrypted file data
encapsulatedKey?: string; // HPKE encapsulated key (optional)
ciphertext?: string; // HPKE ciphertext (optional)
aesKeyBase64?: string; // Direct AES key (optional)
onProgress?: (progress: number) => void;
}Returns:
{
decryptedFile: Blob; // Decrypted file data
success: boolean; // Operation status
error?: string; // Error message if failed
}encapsulateAESKey(recipientPublicKey, aesKeyBase64)
Encapsulate AES key for another user using HPKE.
Parameters:
recipientPublicKey(string): Recipient's HPKE public keyaesKeyBase64(string): AES key to encapsulate
Returns:
{
encapsulatedKey: string; // HPKE encapsulated key
ciphertext: string; // HPKE ciphertext
}HPKEKeyManager
Manage HPKE X25519 key pairs.
import { HPKEKeyManager } from '@everabyte/evb-sdk-typescript/e2ee';
const keyManager = HPKEKeyManager.getInstance();
// Generate key pair
const keyPair = await keyManager.generateKeyPair();
// Store key pair
keyManager.storeKeyPair(userId, keyPair);
// Get public key
const publicKey = keyManager.getPublicKey(userId);
// Get private key
const privateKey = keyManager.getPrivateKey(userId);
// Clear all keys
keyManager.clearAllKeys();❓ FAQ
Q: Is this SDK suitable for production use?
A: Yes! This SDK has 100% test coverage and follows industry best practices for cryptographic implementations.
Q: Can I use this SDK in Node.js?
A: Yes! The SDK now supports Node.js 16.0.0+ out of the box. It automatically detects the environment and uses the appropriate crypto implementation (crypto module for Node.js, Web Crypto API for browsers).
Q: Can I use this SDK in TypeScript?
A: Absolutely! The SDK is written in TypeScript and includes full type definitions. It supports TypeScript 5.0+.
Q: Can I use this SDK in React/Vue/Angular?
A: Yes! The SDK works perfectly with all modern frontend frameworks that support TypeScript. See the React and Vue.js examples above.
Q: How secure is the encryption?
A: The SDK uses:
- AES-256-GCM: Industry-standard symmetric encryption
- HPKE (RFC 9180): IETF-standardized hybrid encryption
- X25519: Modern elliptic curve cryptography
This provides 256-bit security for file encryption and 128-bit security for key exchange.
Q: What happens if I lose my private key?
A: You will permanently lose access to your encrypted files. The server cannot help you recover your data because it never has access to your private keys (zero-knowledge architecture).
Q: Can I share files with other users?
A: Yes! Use the encapsulateAESKey() method to encrypt the file's AES key for a specific recipient's public key.
Q: What's the maximum file size?
A: The SDK supports files of any size through chunked encryption. The default chunk size is 1MB, but you can adjust it based on your needs.
Q: Does the SDK work in React Native?
A: React Native support is planned. You'll need a Web Crypto API polyfill like react-native-webview-crypto or @peculiar/webcrypto to use it in React Native.
📄 License
MIT License - See LICENSE file for details.
🆘 Support
- 📧 Email: [email protected]
- 🐛 Issues: GitLab Issues
- 📖 Documentation: Full Documentation
Made with ❤️ by Everabyte
Website • Documentation • Blog
