Encryption & Security Utilities

Overview

PadawanForge implements a comprehensive encryption and security system that provides secure data handling, token encryption, and cryptographic utilities. This system ensures sensitive data is properly protected throughout the application.

Architecture

Core Components

  • EncryptionService: Centralized encryption/decryption utilities
  • Token Encryption: Secure storage of API keys and tokens
  • Algorithm Support: XOR and AES encryption methods
  • Encoding Options: Base64 and hex encoding support
  • Security Validation: Input sanitization and validation

Security Features

  • Algorithm Flexibility: Support for multiple encryption algorithms
  • Encoding Options: Multiple output encoding formats
  • Error Handling: Graceful failure handling
  • Development Safety: Fallback mechanisms for development environments

Implementation

EncryptionService Class

import { EncryptionService } from '@/lib/utils/encryption';

// Create encryption service with configuration
const encryptionService = new EncryptionService({
  key: 'your-secret-key',
  algorithm: 'xor', // or 'aes'
  encoding: 'base64' // or 'hex'
});

// Encrypt sensitive data
const encrypted = encryptionService.encrypt('sensitive-data');

// Decrypt data
const decrypted = encryptionService.decrypt(encrypted);

Configuration Options

interface EncryptionConfig {
  key: string;                    // Encryption key
  algorithm?: 'xor' | 'aes';      // Encryption algorithm
  encoding?: 'base64' | 'hex';    // Output encoding
}

Simple Encryption Utilities

import { simpleEncrypt, simpleDecrypt } from '@/lib/utils/encryption';

// Quick encryption for simple use cases
const encrypted = simpleEncrypt('data-to-encrypt');
const decrypted = simpleDecrypt(encrypted);

Usage Examples

API Token Encryption

import { EncryptionService } from '@/lib/utils/encryption';

class TokenManager {
  private encryptionService: EncryptionService;

  constructor(secretKey: string) {
    this.encryptionService = new EncryptionService({
      key: secretKey,
      algorithm: 'xor',
      encoding: 'base64'
    });
  }

  // Encrypt API token for storage
  encryptToken(token: string): string {
    return this.encryptionService.encrypt(token);
  }

  // Decrypt API token for use
  decryptToken(encryptedToken: string): string {
    return this.encryptionService.decrypt(encryptedToken);
  }

  // Store encrypted token
  async storeToken(userId: string, token: string): Promise<void> {
    const encryptedToken = this.encryptToken(token);
    
    await db.prepare(`
      INSERT INTO user_tokens (user_id, encrypted_token, created_at)
      VALUES (?, ?, CURRENT_TIMESTAMP)
    `).bind(userId, encryptedToken).run();
  }

  // Retrieve and decrypt token
  async getToken(userId: string): Promise<string | null> {
    const result = await db.prepare(`
      SELECT encrypted_token FROM user_tokens 
      WHERE user_id = ? AND active = true
    `).bind(userId).first();

    if (!result) return null;

    return this.decryptToken(result.encrypted_token);
  }
}

Bot Token Security

import { EncryptionService } from '@/lib/utils/encryption';

class BotTokenService {
  private encryptionService: EncryptionService;

  constructor() {
    this.encryptionService = new EncryptionService({
      key: process.env.BOT_TOKEN_ENCRYPTION_KEY || 'default-key',
      algorithm: 'xor',
      encoding: 'base64'
    });
  }

  // Encrypt bot token before storing
  private encryptToken(token: string): string {
    return this.encryptionService.encrypt(token);
  }

  // Decrypt bot token for API calls
  private decryptToken(encryptedToken: string): string {
    return this.encryptionService.decrypt(encryptedToken);
  }

  // Store bot token securely
  async storeBotToken(platform: string, token: string): Promise<void> {
    const encryptedToken = this.encryptToken(token);
    
    await db.prepare(`
      INSERT INTO bot_tokens (platform, encrypted_token, created_at)
      VALUES (?, ?, CURRENT_TIMESTAMP)
    `).bind(platform, encryptedToken).run();
  }

  // Retrieve bot token for API calls
  async getBotToken(platform: string): Promise<string | null> {
    const result = await db.prepare(`
      SELECT encrypted_token FROM bot_tokens 
      WHERE platform = ? AND active = true
    `).bind(platform).first();

    if (!result) return null;

    return this.decryptToken(result.encrypted_token);
  }
}

Configuration Encryption

import { EncryptionService } from '@/lib/utils/encryption';

class ConfigManager {
  private encryptionService: EncryptionService;

  constructor() {
    this.encryptionService = new EncryptionService({
      key: process.env.CONFIG_ENCRYPTION_KEY || 'config-key',
      algorithm: 'xor',
      encoding: 'base64'
    });
  }

  // Encrypt sensitive configuration
  encryptConfig(config: Record<string, any>): string {
    const configString = JSON.stringify(config);
    return this.encryptionService.encrypt(configString);
  }

  // Decrypt configuration
  decryptConfig(encryptedConfig: string): Record<string, any> {
    const decrypted = this.encryptionService.decrypt(encryptedConfig);
    return JSON.parse(decrypted);
  }

  // Store encrypted configuration
  async storeConfig(key: string, config: Record<string, any>): Promise<void> {
    const encryptedConfig = this.encryptConfig(config);
    
    await db.prepare(`
      INSERT OR REPLACE INTO configurations (config_key, encrypted_value, updated_at)
      VALUES (?, ?, CURRENT_TIMESTAMP)
    `).bind(key, encryptedConfig).run();
  }

  // Retrieve and decrypt configuration
  async getConfig(key: string): Promise<Record<string, any> | null> {
    const result = await db.prepare(`
      SELECT encrypted_value FROM configurations WHERE config_key = ?
    `).bind(key).first();

    if (!result) return null;

    return this.decryptConfig(result.encrypted_value);
  }
}

Security Best Practices

1. Key Management

// Use environment variables for encryption keys
const encryptionService = new EncryptionService({
  key: process.env.ENCRYPTION_KEY || throw new Error('ENCRYPTION_KEY not set'),
  algorithm: 'xor',
  encoding: 'base64'
});

// Rotate keys periodically
class KeyRotationManager {
  async rotateEncryptionKey(oldKey: string, newKey: string): Promise<void> {
    const oldService = new EncryptionService({ key: oldKey });
    const newService = new EncryptionService({ key: newKey });

    // Re-encrypt all sensitive data with new key
    const tokens = await db.prepare('SELECT * FROM encrypted_tokens').all();
    
    for (const token of tokens.results) {
      const decrypted = oldService.decrypt(token.encrypted_value);
      const reEncrypted = newService.encrypt(decrypted);
      
      await db.prepare(`
        UPDATE encrypted_tokens 
        SET encrypted_value = ?, updated_at = CURRENT_TIMESTAMP
        WHERE id = ?
      `).bind(reEncrypted, token.id).run();
    }
  }
}

2. Input Validation

// Validate encryption inputs
class SecureEncryptionService extends EncryptionService {
  encrypt(text: string): string {
    // Validate input
    if (typeof text !== 'string') {
      throw new Error('Input must be a string');
    }
    
    if (text.length === 0) {
      throw new Error('Input cannot be empty');
    }
    
    // Check for maximum length to prevent DoS
    if (text.length > 10000) {
      throw new Error('Input too large for encryption');
    }
    
    return super.encrypt(text);
  }

  decrypt(encryptedText: string): string {
    // Validate encrypted input
    if (typeof encryptedText !== 'string') {
      throw new Error('Encrypted input must be a string');
    }
    
    if (encryptedText.length === 0) {
      throw new Error('Encrypted input cannot be empty');
    }
    
    return super.decrypt(encryptedText);
  }
}

3. Error Handling

// Secure error handling
class SecureTokenManager {
  private encryptionService: EncryptionService;

  constructor(key: string) {
    this.encryptionService = new EncryptionService({ key });
  }

  async decryptTokenSafely(encryptedToken: string): Promise<string | null> {
    try {
      return this.encryptionService.decrypt(encryptedToken);
    } catch (error) {
      // Log error but don't expose details
      console.error('Token decryption failed:', error.message);
      
      // Return null instead of throwing
      return null;
    }
  }

  async encryptTokenSafely(token: string): Promise<string | null> {
    try {
      return this.encryptionService.encrypt(token);
    } catch (error) {
      console.error('Token encryption failed:', error.message);
      return null;
    }
  }
}

Algorithm Details

XOR Encryption

// Simple XOR encryption (for development/demo)
private xorEncrypt(text: string): string {
  let result = '';
  for (let i = 0; i < text.length; i++) {
    result += String.fromCharCode(
      text.charCodeAt(i) ^ this.config.key.charCodeAt(i % this.config.key.length)
    );
  }
  
  if (this.config.encoding === 'base64') {
    return btoa(result);
  } else if (this.config.encoding === 'hex') {
    return Array.from(result)
      .map(c => c.charCodeAt(0).toString(16).padStart(2, '0'))
      .join('');
  }
  
  return result;
}

private xorDecrypt(encryptedText: string): string {
  let decoded: string;
  
  if (this.config.encoding === 'base64') {
    try {
      decoded = atob(encryptedText);
    } catch {
      return '';
    }
  } else if (this.config.encoding === 'hex') {
    try {
      decoded = String.fromCharCode(
        ...encryptedText.match(/.{1,2}/g)!.map(byte => parseInt(byte, 16))
      );
    } catch {
      return '';
    }
  } else {
    decoded = encryptedText;
  }
  
  let result = '';
  for (let i = 0; i < decoded.length; i++) {
    result += String.fromCharCode(
      decoded.charCodeAt(i) ^ this.config.key.charCodeAt(i % this.config.key.length)
    );
  }
  
  return result;
}

AES Encryption (Future Implementation)

// AES encryption (placeholder for future implementation)
private async aesEncrypt(text: string): Promise<string> {
  // Implementation would use Web Crypto API
  // For now, fallback to XOR
  console.warn('AES encryption not implemented, falling back to XOR');
  return this.xorEncrypt(text);
}

private async aesDecrypt(encryptedText: string): Promise<string> {
  // Implementation would use Web Crypto API
  // For now, fallback to XOR
  console.warn('AES decryption not implemented, falling back to XOR');
  return this.xorDecrypt(encryptedText);
}

Integration Examples

Database Integration

// Secure database operations
class SecureDatabaseService {
  private encryptionService: EncryptionService;

  constructor() {
    this.encryptionService = new EncryptionService({
      key: process.env.DB_ENCRYPTION_KEY || 'db-key',
      algorithm: 'xor',
      encoding: 'base64'
    });
  }

  // Store sensitive user data
  async storeUserData(userId: string, sensitiveData: Record<string, any>): Promise<void> {
    const encryptedData = this.encryptionService.encrypt(JSON.stringify(sensitiveData));
    
    await db.prepare(`
      INSERT OR REPLACE INTO user_sensitive_data (user_id, encrypted_data, updated_at)
      VALUES (?, ?, CURRENT_TIMESTAMP)
    `).bind(userId, encryptedData).run();
  }

  // Retrieve sensitive user data
  async getUserData(userId: string): Promise<Record<string, any> | null> {
    const result = await db.prepare(`
      SELECT encrypted_data FROM user_sensitive_data WHERE user_id = ?
    `).bind(userId).first();

    if (!result) return null;

    const decrypted = this.encryptionService.decrypt(result.encrypted_data);
    return JSON.parse(decrypted);
  }
}

API Integration

// Secure API token handling
class SecureAPIService {
  private encryptionService: EncryptionService;

  constructor() {
    this.encryptionService = new EncryptionService({
      key: process.env.API_ENCRYPTION_KEY || 'api-key',
      algorithm: 'xor',
      encoding: 'base64'
    });
  }

  // Store API credentials securely
  async storeAPICredentials(serviceName: string, credentials: {
    apiKey: string;
    secretKey?: string;
    endpoint?: string;
  }): Promise<void> {
    const encryptedCredentials = this.encryptionService.encrypt(
      JSON.stringify(credentials)
    );
    
    await db.prepare(`
      INSERT OR REPLACE INTO api_credentials (service_name, encrypted_credentials, updated_at)
      VALUES (?, ?, CURRENT_TIMESTAMP)
    `).bind(serviceName, encryptedCredentials).run();
  }

  // Retrieve API credentials
  async getAPICredentials(serviceName: string): Promise<{
    apiKey: string;
    secretKey?: string;
    endpoint?: string;
  } | null> {
    const result = await db.prepare(`
      SELECT encrypted_credentials FROM api_credentials WHERE service_name = ?
    `).bind(serviceName).first();

    if (!result) return null;

    const decrypted = this.encryptionService.decrypt(result.encrypted_credentials);
    return JSON.parse(decrypted);
  }
}

Testing

Encryption Testing

describe('EncryptionService', () => {
  let encryptionService: EncryptionService;

  beforeEach(() => {
    encryptionService = new EncryptionService({
      key: 'test-key-123',
      algorithm: 'xor',
      encoding: 'base64'
    });
  });

  it('should encrypt and decrypt data correctly', () => {
    const originalData = 'sensitive-information';
    const encrypted = encryptionService.encrypt(originalData);
    const decrypted = encryptionService.decrypt(encrypted);
    
    expect(decrypted).toBe(originalData);
    expect(encrypted).not.toBe(originalData);
  });

  it('should handle empty strings', () => {
    const encrypted = encryptionService.encrypt('');
    const decrypted = encryptionService.decrypt(encrypted);
    
    expect(decrypted).toBe('');
  });

  it('should handle special characters', () => {
    const originalData = 'special-chars: !@#$%^&*()_+-=[]{}|;:,.<>?';
    const encrypted = encryptionService.encrypt(originalData);
    const decrypted = encryptionService.decrypt(encrypted);
    
    expect(decrypted).toBe(originalData);
  });
});

Security Testing

describe('Security Features', () => {
  it('should not expose encryption key in output', () => {
    const encryptionService = new EncryptionService({
      key: 'secret-key',
      algorithm: 'xor',
      encoding: 'base64'
    });

    const encrypted = encryptionService.encrypt('test-data');
    
    // Encrypted output should not contain the key
    expect(encrypted).not.toContain('secret-key');
  });

  it('should handle invalid encrypted input gracefully', () => {
    const encryptionService = new EncryptionService({
      key: 'test-key',
      algorithm: 'xor',
      encoding: 'base64'
    });

    const result = encryptionService.decrypt('invalid-base64');
    expect(result).toBe('');
  });
});

This encryption and security system provides robust protection for sensitive data throughout the PadawanForge application.

PadawanForge v1.4.1