💎 🔒 Advanced Encryption with TuskLang Ruby

Ruby Documentation

🔒 Advanced Encryption with TuskLang Ruby

"We don't bow to any king" - Ruby Edition

Implement enterprise-grade encryption with TuskLang's advanced encryption features. From data-at-rest encryption to secure key management, TuskLang provides the security and flexibility you need to protect sensitive data in your Ruby applications.

🚀 Quick Start

Basic Encryption Setup

require 'tusklang'
require 'tusklang/encryption'

Initialize encryption system

encryption_system = TuskLang::Encryption::System.new

Configure encryption

encryption_system.configure do |config| config.default_algorithm = 'AES-256-GCM' config.key_rotation_enabled = true config.key_rotation_interval = 30.days config.master_key_source = 'aws-kms' end

Register encryption strategies

encryption_system.register_strategy(:aes, TuskLang::Encryption::Strategies::AESStrategy.new) encryption_system.register_strategy(:rsa, TuskLang::Encryption::Strategies::RSAStrategy.new) encryption_system.register_strategy(:chacha20, TuskLang::Encryption::Strategies::ChaCha20Strategy.new)

TuskLang Configuration

config/encryption.tsk

[encryption] enabled: true default_algorithm: "AES-256-GCM" key_rotation_enabled: true key_rotation_interval: "30d" master_key_source: "aws-kms"

[encryption.keys] master_key_id: @env("MASTER_KEY_ID", "alias/myapp-master-key") data_key_id: @env("DATA_KEY_ID", "alias/myapp-data-key") backup_key_id: @env("BACKUP_KEY_ID", "alias/myapp-backup-key")

[encryption.algorithms] aes_256_gcm: { key_size: 256, iv_size: 12, tag_size: 16, mode: "GCM" } aes_256_cbc: { key_size: 256, iv_size: 16, mode: "CBC" } chacha20_poly1305: { key_size: 256, nonce_size: 12, tag_size: 16, mode: "ChaCha20-Poly1305" }

[encryption.key_management] aws_kms: { region: @env("AWS_REGION", "us-east-1"), access_key_id: @env("AWS_ACCESS_KEY_ID"), secret_access_key: @env("AWS_SECRET_ACCESS_KEY") } vault: { url: @env("VAULT_URL", "http://localhost:8200"), token: @env("VAULT_TOKEN"), mount_path: "transit" }

🎯 Core Features

1. AES Encryption Strategy

require 'tusklang/encryption'
require 'openssl'

class AESStrategy include TuskLang::Encryption::Strategy def initialize(algorithm: 'AES-256-GCM') @algorithm = algorithm @config = TuskLang.parse_file('config/encryption.tsk') @key_manager = KeyManager.new end def encrypt(data, context = {}) # Generate or retrieve encryption key key = @key_manager.get_encryption_key(context) case @algorithm when 'AES-256-GCM' encrypt_aes_gcm(data, key) when 'AES-256-CBC' encrypt_aes_cbc(data, key) else raise "Unsupported AES algorithm: #{@algorithm}" end end def decrypt(encrypted_data, context = {}) # Parse encrypted data parsed_data = parse_encrypted_data(encrypted_data) # Retrieve decryption key key = @key_manager.get_decryption_key(parsed_data[:key_id], context) case parsed_data[:algorithm] when 'AES-256-GCM' decrypt_aes_gcm(parsed_data, key) when 'AES-256-CBC' decrypt_aes_cbc(parsed_data, key) else raise "Unsupported AES algorithm: #{parsed_data[:algorithm]}" end end private def encrypt_aes_gcm(data, key) cipher = OpenSSL::Cipher.new('aes-256-gcm') cipher.encrypt cipher.key = key # Generate random IV iv = cipher.random_iv # Encrypt data encrypted = cipher.update(data) + cipher.final tag = cipher.auth_tag # Create encrypted data structure { algorithm: 'AES-256-GCM', key_id: key[:key_id], iv: Base64.strict_encode64(iv), encrypted_data: Base64.strict_encode64(encrypted), auth_tag: Base64.strict_encode64(tag), version: '1.0' } end def decrypt_aes_gcm(parsed_data, key) cipher = OpenSSL::Cipher.new('aes-256-gcm') cipher.decrypt cipher.key = key[:key] cipher.iv = Base64.strict_decode64(parsed_data[:iv]) cipher.auth_tag = Base64.strict_decode64(parsed_data[:auth_tag]) cipher.auth_data = '' # Decrypt data encrypted = Base64.strict_decode64(parsed_data[:encrypted_data]) cipher.update(encrypted) + cipher.final rescue OpenSSL::Cipher::CipherError => e raise EncryptionError, "Decryption failed: #{e.message}" end def encrypt_aes_cbc(data, key) cipher = OpenSSL::Cipher.new('aes-256-cbc') cipher.encrypt cipher.key = key # Generate random IV iv = cipher.random_iv # Pad data to block size padded_data = pad_data(data, cipher.block_size) # Encrypt data encrypted = cipher.update(padded_data) + cipher.final # Create encrypted data structure { algorithm: 'AES-256-CBC', key_id: key[:key_id], iv: Base64.strict_encode64(iv), encrypted_data: Base64.strict_encode64(encrypted), version: '1.0' } end def decrypt_aes_cbc(parsed_data, key) cipher = OpenSSL::Cipher.new('aes-256-cbc') cipher.decrypt cipher.key = key[:key] cipher.iv = Base64.strict_decode64(parsed_data[:iv]) # Decrypt data encrypted = Base64.strict_decode64(parsed_data[:encrypted_data]) decrypted = cipher.update(encrypted) + cipher.final # Remove padding unpad_data(decrypted) rescue OpenSSL::Cipher::CipherError => e raise EncryptionError, "Decryption failed: #{e.message}" end def parse_encrypted_data(encrypted_data) if encrypted_data.is_a?(String) JSON.parse(encrypted_data, symbolize_names: true) else encrypted_data end end def pad_data(data, block_size) padding_length = block_size - (data.bytesize % block_size) data + padding_length.chr * padding_length end def unpad_data(data) padding_length = data.bytes.last data[0...-padding_length] end end

2. RSA Encryption Strategy

require 'tusklang/encryption'
require 'openssl'

class RSAStrategy include TuskLang::Encryption::Strategy def initialize(key_size: 2048) @key_size = key_size @config = TuskLang.parse_file('config/encryption.tsk') @key_manager = KeyManager.new end def encrypt(data, context = {}) # RSA is typically used for key encryption, not data encryption # For large data, we'll use hybrid encryption (RSA + AES) if data.bytesize > max_data_size return hybrid_encrypt(data, context) else return rsa_encrypt(data, context) end end def decrypt(encrypted_data, context = {}) parsed_data = parse_encrypted_data(encrypted_data) case parsed_data[:encryption_type] when 'hybrid' hybrid_decrypt(parsed_data, context) when 'rsa' rsa_decrypt(parsed_data, context) else raise "Unknown encryption type: #{parsed_data[:encryption_type]}" end end def generate_key_pair private_key = OpenSSL::PKey::RSA.new(@key_size) public_key = private_key.public_key { private_key: private_key.to_pem, public_key: public_key.to_pem, key_id: SecureRandom.uuid } end private def max_data_size (@key_size / 8) - 42 # RSA padding overhead end def hybrid_encrypt(data, context) # Generate AES key for data encryption aes_key = SecureRandom.random_bytes(32) # Encrypt data with AES aes_strategy = AESStrategy.new(algorithm: 'AES-256-GCM') encrypted_data = aes_strategy.encrypt(data, { key: aes_key }) # Encrypt AES key with RSA rsa_key = @key_manager.get_rsa_public_key(context) encrypted_key = rsa_key.public_encrypt(aes_key, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING) { encryption_type: 'hybrid', algorithm: 'RSA-AES-256-GCM', key_id: rsa_key[:key_id], encrypted_key: Base64.strict_encode64(encrypted_key), encrypted_data: encrypted_data, version: '1.0' } end def hybrid_decrypt(parsed_data, context) # Decrypt AES key with RSA rsa_key = @key_manager.get_rsa_private_key(parsed_data[:key_id], context) encrypted_key = Base64.strict_decode64(parsed_data[:encrypted_key]) aes_key = rsa_key.private_decrypt(encrypted_key, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING) # Decrypt data with AES aes_strategy = AESStrategy.new(algorithm: 'AES-256-GCM') aes_strategy.decrypt(parsed_data[:encrypted_data], { key: aes_key }) end def rsa_encrypt(data, context) rsa_key = @key_manager.get_rsa_public_key(context) encrypted = rsa_key.public_encrypt(data, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING) { encryption_type: 'rsa', algorithm: 'RSA', key_id: rsa_key[:key_id], encrypted_data: Base64.strict_encode64(encrypted), version: '1.0' } end def rsa_decrypt(parsed_data, context) rsa_key = @key_manager.get_rsa_private_key(parsed_data[:key_id], context) encrypted = Base64.strict_decode64(parsed_data[:encrypted_data]) rsa_key.private_decrypt(encrypted, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING) end def parse_encrypted_data(encrypted_data) if encrypted_data.is_a?(String) JSON.parse(encrypted_data, symbolize_names: true) else encrypted_data end end end

3. ChaCha20-Poly1305 Strategy

require 'tusklang/encryption'

class ChaCha20Strategy include TuskLang::Encryption::Strategy def initialize @config = TuskLang.parse_file('config/encryption.tsk') @key_manager = KeyManager.new end def encrypt(data, context = {}) key = @key_manager.get_encryption_key(context) nonce = SecureRandom.random_bytes(12) # Use ChaCha20-Poly1305 for encryption cipher = OpenSSL::Cipher.new('chacha20-poly1305') cipher.encrypt cipher.key = key cipher.iv = nonce encrypted = cipher.update(data) + cipher.final tag = cipher.auth_tag { algorithm: 'ChaCha20-Poly1305', key_id: key[:key_id], nonce: Base64.strict_encode64(nonce), encrypted_data: Base64.strict_encode64(encrypted), auth_tag: Base64.strict_encode64(tag), version: '1.0' } end def decrypt(encrypted_data, context = {}) parsed_data = parse_encrypted_data(encrypted_data) key = @key_manager.get_decryption_key(parsed_data[:key_id], context) cipher = OpenSSL::Cipher.new('chacha20-poly1305') cipher.decrypt cipher.key = key[:key] cipher.iv = Base64.strict_decode64(parsed_data[:nonce]) cipher.auth_tag = Base64.strict_decode64(parsed_data[:auth_tag]) cipher.auth_data = '' encrypted = Base64.strict_decode64(parsed_data[:encrypted_data]) cipher.update(encrypted) + cipher.final rescue OpenSSL::Cipher::CipherError => e raise EncryptionError, "Decryption failed: #{e.message}" end private def parse_encrypted_data(encrypted_data) if encrypted_data.is_a?(String) JSON.parse(encrypted_data, symbolize_names: true) else encrypted_data end end end

4. Key Management System

require 'tusklang/encryption'
require 'aws-sdk-kms'

class KeyManager def initialize @config = TuskLang.parse_file('config/encryption.tsk') @cache = {} setup_key_sources end def get_encryption_key(context = {}) key_source = context[:key_source] || @config['encryption']['master_key_source'] case key_source when 'aws-kms' get_aws_kms_key(context) when 'vault' get_vault_key(context) when 'local' get_local_key(context) else raise "Unknown key source: #{key_source}" end end def get_decryption_key(key_id, context = {}) cache_key = "decrypt_key:#{key_id}" # Check cache first return @cache[cache_key] if @cache[cache_key] # Retrieve key from source key = retrieve_key_from_source(key_id, context) # Cache key @cache[cache_key] = key key end def rotate_keys # Generate new keys new_keys = generate_new_keys # Update key references update_key_references(new_keys) # Clean up old keys cleanup_old_keys new_keys end private def setup_key_sources case @config['encryption']['master_key_source'] when 'aws-kms' @kms_client = Aws::KMS::Client.new( region: @config['encryption']['key_management']['aws_kms']['region'], credentials: Aws::Credentials.new( @config['encryption']['key_management']['aws_kms']['access_key_id'], @config['encryption']['key_management']['aws_kms']['secret_access_key'] ) ) when 'vault' @vault_client = Vault::Client.new( address: @config['encryption']['key_management']['vault']['url'], token: @config['encryption']['key_management']['vault']['token'] ) end end def get_aws_kms_key(context) key_id = context[:key_id] || @config['encryption']['keys']['data_key_id'] # Generate data key from KMS response = @kms_client.generate_data_key( key_id: key_id, key_spec: 'AES_256' ) { key: response.plaintext, key_id: key_id, encrypted_key: response.ciphertext_blob } end def get_vault_key(context) key_id = context[:key_id] || 'default' # Get key from Vault response = @vault_client.logical.read("transit/keys/#{key_id}") { key: response.data[:keys][:1], key_id: key_id } end def get_local_key(context) key_id = context[:key_id] || 'default' # Get key from local storage key_file = "config/keys/#{key_id}.key" if File.exist?(key_file) { key: File.read(key_file), key_id: key_id } else raise "Local key not found: #{key_id}" end end def retrieve_key_from_source(key_id, context) # Implementation depends on key source case @config['encryption']['master_key_source'] when 'aws-kms' retrieve_aws_kms_key(key_id) when 'vault' retrieve_vault_key(key_id) when 'local' retrieve_local_key(key_id) end end def generate_new_keys case @config['encryption']['master_key_source'] when 'aws-kms' generate_aws_kms_keys when 'vault' generate_vault_keys when 'local' generate_local_keys end end def update_key_references(new_keys) # Update configuration with new key references # Implementation depends on storage mechanism end def cleanup_old_keys # Remove old keys from storage # Implementation depends on storage mechanism end end

5. Database Field Encryption

require 'tusklang/encryption'

module Encryptable extend ActiveSupport::Concern included do before_save :encrypt_sensitive_fields after_find :decrypt_sensitive_fields end class_methods do def encrypts(fields, *options) @encrypted_fields ||= [] @encrypted_fields.concat(fields.map(&:to_s)) fields.each do |field| define_method("#{field}=") do |value| instance_variable_set("@#{field}_encrypted", true) super(value) end end end def encrypted_fields @encrypted_fields || [] end end private def encrypt_sensitive_fields self.class.encrypted_fields.each do |field| value = send(field) next if value.nil? || instance_variable_get("@#{field}_encrypted") encrypted_value = encrypt_field_value(value, field) write_attribute(field, encrypted_value) end end def decrypt_sensitive_fields self.class.encrypted_fields.each do |field| value = read_attribute(field) next if value.nil? decrypted_value = decrypt_field_value(value, field) write_attribute(field, decrypted_value) end end def encrypt_field_value(value, field) encryption_system = TuskLang::Encryption::System.new encrypted = encryption_system.encrypt(value.to_s, { field: field }) encrypted.to_json end def decrypt_field_value(value, field) return value unless value.is_a?(String) begin encrypted_data = JSON.parse(value) encryption_system = TuskLang::Encryption::System.new encryption_system.decrypt(encrypted_data, { field: field }) rescue JSON::ParserError # Value is not encrypted, return as-is value end end end

Usage in models

class User < ApplicationRecord include Encryptable encrypts :ssn, :credit_card_number, :medical_records end

class Order < ApplicationRecord include Encryptable encrypts :customer_notes, :payment_details end

6. File Encryption

require 'tusklang/encryption'

class FileEncryption def initialize @config = TuskLang.parse_file('config/encryption.tsk') @encryption_system = TuskLang::Encryption::System.new end def encrypt_file(input_path, output_path, context = {}) # Read file in chunks to handle large files chunk_size = 1024 * 1024 # 1MB chunks File.open(output_path, 'wb') do |output_file| # Write encryption header header = generate_encryption_header(context) output_file.write(header.to_json + "\n") # Encrypt file content File.open(input_path, 'rb') do |input_file| while chunk = input_file.read(chunk_size) encrypted_chunk = @encryption_system.encrypt(chunk, context) output_file.write(encrypted_chunk.to_json + "\n") end end end end def decrypt_file(input_path, output_path, context = {}) File.open(output_path, 'wb') do |output_file| File.open(input_path, 'r') do |input_file| # Skip header input_file.readline # Decrypt file content input_file.each_line do |line| encrypted_chunk = JSON.parse(line.strip, symbolize_names: true) decrypted_chunk = @encryption_system.decrypt(encrypted_chunk, context) output_file.write(decrypted_chunk) end end end end def encrypt_stream(input_stream, output_stream, context = {}) # Write encryption header header = generate_encryption_header(context) output_stream.write(header.to_json + "\n") # Encrypt stream content input_stream.each_line do |line| encrypted_line = @encryption_system.encrypt(line, context) output_stream.write(encrypted_line.to_json + "\n") end end private def generate_encryption_header(context) { algorithm: @config['encryption']['default_algorithm'], version: '1.0', timestamp: Time.now.iso8601, context: context } end end

🔧 Advanced Configuration

Encryption Middleware

require 'tusklang/encryption'

class EncryptionMiddleware def initialize(app) @app = app @config = TuskLang.parse_file('config/encryption.tsk') @encryption_system = TuskLang::Encryption::System.new end def call(env) request = Rack::Request.new(env) # Encrypt sensitive response data status, headers, response = @app.call(env) if should_encrypt_response?(request, headers) encrypted_response = encrypt_response(response, request) [status, headers, encrypted_response] else [status, headers, response] end end private def should_encrypt_response?(request, headers) # Check if response contains sensitive data content_type = headers['Content-Type'] return false unless content_type&.include?('application/json') # Check request path for sensitive endpoints sensitive_paths = @config['encryption']['sensitive_paths'] || [] sensitive_paths.any? { |path| request.path.start_with?(path) } end def encrypt_response(response, request) # Parse response body body = response.join data = JSON.parse(body) # Encrypt sensitive fields encrypted_data = encrypt_sensitive_fields(data, request) # Return encrypted response [encrypted_data.to_json] end def encrypt_sensitive_fields(data, request) if data.is_a?(Hash) data.transform_values { |value| encrypt_sensitive_fields(value, request) } elsif data.is_a?(Array) data.map { |item| encrypt_sensitive_fields(item, request) } else # Check if field should be encrypted if should_encrypt_field?(data, request) @encryption_system.encrypt(data.to_s, { request: request }) else data end end end def should_encrypt_field?(value, request) # Implementation to determine if field should be encrypted # based on field name, value type, or request context false end end

🚀 Performance Optimization

Encryption Caching

require 'tusklang/encryption'

class EncryptionCache def initialize @cache = TuskLang::Cache::RedisCache.new @config = TuskLang.parse_file('config/encryption.tsk') end def cache_encrypted_value(key, value, context_hash) cache_key = generate_cache_key(key, context_hash) ttl = parse_duration(@config['encryption']['cache_ttl']) @cache.set(cache_key, value, ttl) end def get_cached_encrypted_value(key, context_hash) cache_key = generate_cache_key(key, context_hash) @cache.get(cache_key) end def invalidate_key_cache(key_id) pattern = "encrypt:#{key_id}:*" @cache.delete_pattern(pattern) end private def generate_cache_key(key, context_hash) "encrypt:#{key}:#{context_hash}" end def parse_duration(duration_string) case duration_string when /(\d+)h/ $1.to_i * 3600 when /(\d+)m/ $1.to_i * 60 else 3600 # Default 1 hour end end end

📊 Monitoring and Analytics

Encryption Analytics

require 'tusklang/encryption'

class EncryptionAnalytics def initialize @metrics = TuskLang::Metrics::Collector.new end def track_encryption_operation(operation, algorithm, data_size, success) @metrics.increment("encryption.operations.total") @metrics.increment("encryption.operations.#{operation}") @metrics.increment("encryption.operations.#{operation}.#{success ? 'success' : 'failure'}") @metrics.increment("encryption.algorithms.#{algorithm}") @metrics.histogram("encryption.data_size", data_size) end def track_key_usage(key_id, operation) @metrics.increment("encryption.keys.#{key_id}.#{operation}") end def get_encryption_stats { total_operations: @metrics.get("encryption.operations.total"), success_rate: @metrics.get_success_rate("encryption.operations"), popular_algorithms: @metrics.get_top("encryption.algorithms", 5), average_data_size: @metrics.get_average("encryption.data_size") } end end

This comprehensive encryption system provides enterprise-grade security features while maintaining the flexibility and power of TuskLang. The combination of multiple encryption algorithms, key management systems, and performance optimizations creates a robust foundation for protecting sensitive data in Ruby applications.