Encryption at Rest and in Transit: Comprehensive Data Protection
Whitespots Team ·
encryption
data-protection
cryptography
Introduction
Encryption protects sensitive data from unauthorized access both when stored and during transmission. This guide covers implementing encryption at rest and in transit with practical examples.
Encryption at Rest
Database Encryption
javascript// Field-level encryption with Node.js const crypto = require('crypto'); const ENCRYPTION_KEY = Buffer.from(process.env.ENCRYPTION_KEY, 'hex'); const IV_LENGTH = 16; function encrypt(text) { const iv = crypto.randomBytes(IV_LENGTH); const cipher = crypto.createCipheriv('aes-256-gcm', ENCRYPTION_KEY, iv); let encrypted = cipher.update(text, 'utf8', 'hex'); encrypted += cipher.final('hex'); const authTag = cipher.getAuthTag(); return { iv: iv.toString('hex'), encrypted, authTag: authTag.toString('hex') }; } function decrypt(encryptedData) { const decipher = crypto.createDecipheriv( 'aes-256-gcm', ENCRYPTION_KEY, Buffer.from(encryptedData.iv, 'hex') ); decipher.setAuthTag(Buffer.from(encryptedData.authTag, 'hex')); let decrypted = decipher.update(encryptedData.encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } // Usage const user = { email: 'user@example.com', ssn: encrypt('123-45-6789') }; await db.users.create(user);
File Encryption
javascriptconst fs = require('fs'); const crypto = require('crypto'); const stream = require('stream'); const { promisify } = require('util'); const pipeline = promisify(stream.pipeline); async function encryptFile(inputPath, outputPath, key) { const iv = crypto.randomBytes(16); // Write IV to beginning of file await fs.promises.writeFile(outputPath, iv); const cipher = crypto.createCipheriv('aes-256-cbc', key, iv); const input = fs.createReadStream(inputPath); const output = fs.createWriteStream(outputPath, { flags: 'a' }); await pipeline(input, cipher, output); } async function decryptFile(inputPath, outputPath, key) { // Read IV from beginning of file const fd = await fs.promises.open(inputPath, 'r'); const iv = Buffer.alloc(16); await fd.read(iv, 0, 16, 0); await fd.close(); const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); const input = fs.createReadStream(inputPath, { start: 16 }); const output = fs.createWriteStream(outputPath); await pipeline(input, decipher, output); }
AWS S3 Encryption
javascriptconst AWS = require('aws-sdk'); const s3 = new AWS.S3(); // Server-side encryption with S3-managed keys (SSE-S3) await s3.putObject({ Bucket: 'my-bucket', Key: 'file.pdf', Body: fileContent, ServerSideEncryption: 'AES256' }).promise(); // Server-side encryption with KMS (SSE-KMS) await s3.putObject({ Bucket: 'my-bucket', Key: 'sensitive-file.pdf', Body: fileContent, ServerSideEncryption: 'aws:kms', SSEKMSKeyId: 'arn:aws:kms:region:account:key/key-id' }).promise(); // Client-side encryption const encryptedData = encrypt(fileContent); await s3.putObject({ Bucket: 'my-bucket', Key: 'file.pdf.encrypted', Body: JSON.stringify(encryptedData) }).promise();
Encryption in Transit
HTTPS Implementation
javascriptconst express = require('express'); const https = require('https'); const fs = require('fs'); const app = express(); const options = { key: fs.readFileSync('privkey.pem'), cert: fs.readFileSync('fullchain.pem'), minVersion: 'TLSv1.2' }; https.createServer(options, app).listen(443); // Redirect HTTP to HTTPS const http = require('http'); http.createServer((req, res) => { res.writeHead(301, { Location: `https://${req.headers.host}${req.url}` }); res.end(); }).listen(80);
API Client with TLS
javascriptconst axios = require('axios'); const https = require('https'); const fs = require('fs'); const httpsAgent = new https.Agent({ // Client certificate for mTLS cert: fs.readFileSync('client-cert.pem'), key: fs.readFileSync('client-key.pem'), ca: fs.readFileSync('ca-cert.pem'), // Reject unauthorized certs rejectUnauthorized: true, // TLS version minVersion: 'TLSv1.2' }); const response = await axios.get('https://api.example.com/data', { httpsAgent });
Key Management
javascript// AWS KMS for key management const { KMSClient, EncryptCommand, DecryptCommand } = require('@aws-sdk/client-kms'); const kmsClient = new KMSClient({ region: 'us-east-1' }); async function encryptWithKMS(plaintext, keyId) { const command = new EncryptCommand({ KeyId: keyId, Plaintext: Buffer.from(plaintext) }); const response = await kmsClient.send(command); return response.CiphertextBlob.toString('base64'); } async function decryptWithKMS(ciphertext) { const command = new DecryptCommand({ CiphertextBlob: Buffer.from(ciphertext, 'base64') }); const response = await kmsClient.send(command); return response.Plaintext.toString('utf8'); }
Encryption Best Practices
- ✅ Use AES-256 for symmetric encryption
- ✅ Use RSA-2048+ for asymmetric encryption
- ✅ Never hardcode encryption keys
- ✅ Use secure key derivation (PBKDF2, Argon2)
- ✅ Rotate encryption keys regularly
- ✅ Use authenticated encryption (GCM mode)
- ✅ Store keys in KMS or HSM
- ✅ Encrypt sensitive database fields
- ✅ Use TLS 1.2+ for transit
- ✅ Implement end-to-end encryption
- ✅ Regular cryptographic audits
Conclusion
Comprehensive encryption at rest and in transit protects data throughout its lifecycle. Implement strong encryption algorithms, proper key management, and TLS for complete data protection.
