Data Encoding Fundamentals
Data encoding is the process of converting data from one format to another to ensure safe transmission, storage, and processing. Understanding different encoding schemes and their appropriate use cases is crucial for secure data handling.
π Common Encoding Types
π§ Base64 Encoding
Convert binary data to text format
// JavaScript Base64 encoding/decoding
const originalString = "Hello, World! π";
// Encoding
const encoded = btoa(originalString);
console.log(encoded); // "SGVsbG8sIFdvcmxkISDwn5iB"
// Decoding
const decoded = atob(encoded);
console.log(decoded); // "Hello, World! π"
// For Unicode strings
const utf8Bytes = new TextEncoder().encode(originalString);
const base64 = btoa(String.fromCharCode(...utf8Bytes));
const decodedBytes = Uint8Array.from(atob(base64), c => c.charCodeAt(0));
const decodedString = new TextDecoder().decode(decodedBytes);
Use Cases:
- Embedding binary data in text formats (JSON, XML)
- Basic obfuscation (not encryption)
- Data URIs for images
- HTTP Basic Authentication
Security Note:
Base64 is encoding, not encryption. It provides no security benefits.
π’ Hexadecimal Encoding
Convert bytes to hexadecimal representation
// Convert string to hex
function stringToHex(str) {
return Array.from(str)
.map(char => char.charCodeAt(0).toString(16).padStart(2, '0'))
.join('');
}
// Convert hex back to string
function hexToString(hex) {
const bytes = [];
for (let i = 0; i < hex.length; i += 2) {
bytes.push(parseInt(hex.substr(i, 2), 16));
}
return String.fromCharCode(...bytes);
}
// Usage
const original = "Hello";
const hex = stringToHex(original);
console.log(hex); // "48656c6c6f"
const back = hexToString(hex);
console.log(back); // "Hello"
// ArrayBuffer to hex
function arrayBufferToHex(buffer) {
return Array.from(new Uint8Array(buffer))
.map(byte => byte.toString(16).padStart(2, '0'))
.join('');
}
Use Cases:
- Displaying binary data in logs
- Hash representations (MD5, SHA-256)
- Color codes in CSS/HTML
- Memory addresses and debugging
π URL Encoding
Encode data for safe URL transmission
// JavaScript URL encoding
const data = "Hello World & Special Characters!";
// encodeURIComponent (for URL components)
const encoded = encodeURIComponent(data);
console.log(encoded); // "Hello%20World%20%26%20Special%20Characters%21"
// encodeURI (for complete URLs)
const url = "https://example.com/search?q=" + encodeURIComponent("node.js & react");
console.log(url);
// Decoding
const decoded = decodeURIComponent(encoded);
console.log(decoded); // "Hello World & Special Characters!"
// Manual URL encoding
function customUrlEncode(str) {
return str.replace(/[^a-zA-Z0-9]/g, char => {
return '%' + char.charCodeAt(0).toString(16).toUpperCase();
});
}
// Handle special characters properly
function safeUrlEncode(obj) {
return Object.keys(obj).map(key => {
return encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]);
}).join('&');
}
Use Cases:
- Query parameters in URLs
- Form data submission
- API endpoints with special characters
- Preventing URL injection attacks
π HTML Entity Encoding
Encode HTML special characters
// HTML entity encoding
function htmlEncode(str) {
const entityMap = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'/': '/',
'`': '`',
'=': '='
};
return str.replace(/[&<>"'`=]/g, char => entityMap[char]);
}
// Usage
const userInput = '';
const safeHtml = htmlEncode(userInput);
console.log(safeHtml); // "<script>alert("XSS")</script>"
// Decoding
function htmlDecode(str) {
const entityMap = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
''': "'",
'/': '/',
'`': '`',
'=': '='
};
return str.replace(/&[a-zA-Z0-9#]+;/g, entity => entityMap[entity] || entity);
}
Use Cases:
- Preventing XSS attacks
- Displaying user-generated content
- HTML attribute values
- JSON in HTML contexts
Cryptography Basics
π Cryptographic Concepts
Understanding the fundamental concepts of cryptography is essential for implementing secure data handling.
π Symmetric Encryption
Same key for encryption and decryption
const crypto = require('crypto');
// AES-256 encryption
function encrypt(text, key) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipher('aes-256-cbc', key);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return {
iv: iv.toString('hex'),
encryptedData: encrypted
};
}
function decrypt(encrypted, key, iv) {
const decipher = crypto.createDecipher('aes-256-cbc', key);
decipher.setAutoPadding(false);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
// Usage
const key = crypto.randomBytes(32); // 256-bit key
const data = "Sensitive information";
const encrypted = encrypt(data, key);
console.log("Encrypted:", encrypted);
const decrypted = decrypt(encrypted.encryptedData, key, encrypted.iv);
console.log("Decrypted:", decrypted);
Algorithms:
- AES (Advanced Encryption Standard)
- DES (Data Encryption Standard)
- 3DES (Triple DES)
- ChaCha20
π Asymmetric Encryption
Public key for encryption, private key for decryption
const crypto = require('crypto');
// Generate key pair
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem'
}
});
// Encrypt with public key
function encryptWithPublicKey(data, publicKey) {
return crypto.publicEncrypt(
{
key: publicKey,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: "sha256"
},
Buffer.from(data)
).toString('base64');
}
// Decrypt with private key
function decryptWithPrivateKey(encryptedData, privateKey) {
return crypto.privateDecrypt(
{
key: privateKey,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: "sha256"
},
Buffer.from(encryptedData, 'base64')
).toString();
}
// Usage
const message = "Secret message";
const encrypted = encryptWithPublicKey(message, publicKey);
const decrypted = decryptWithPrivateKey(encrypted, privateKey);
console.log("Original:", message);
console.log("Decrypted:", decrypted);
Use Cases:
- Digital signatures
- Key exchange protocols
- SSL/TLS certificates
- Secure communication
π Hashing
One-way functions for data integrity and passwords
const crypto = require('crypto');
// Simple hashing
function hashData(data, algorithm = 'sha256') {
return crypto.createHash(algorithm).update(data).digest('hex');
}
// Password hashing with salt
function hashPassword(password) {
const salt = crypto.randomBytes(16).toString('hex');
const hash = crypto.pbkdf2Sync(password, salt, 1000, 64, 'sha512').toString('hex');
return { salt, hash };
}
function verifyPassword(password, salt, hash) {
const verifyHash = crypto.pbkdf2Sync(password, salt, 1000, 64, 'sha512').toString('hex');
return hash === verifyHash;
}
// HMAC for integrity verification
function createHMAC(data, key, algorithm = 'sha256') {
return crypto.createHmac(algorithm, key).update(data).digest('hex');
}
function verifyHMAC(data, key, hmac, algorithm = 'sha256') {
const computed = createHMAC(data, key, algorithm);
return crypto.timingSafeEqual(
Buffer.from(hmac, 'hex'),
Buffer.from(computed, 'hex')
);
}
// Usage
const data = "Important data";
const password = "userPassword123";
console.log("SHA-256:", hashData(data));
console.log("Password hash:", hashPassword(password));
// HMAC usage
const key = crypto.randomBytes(32);
const hmac = createHMAC(data, key);
console.log("HMAC valid:", verifyHMAC(data, key, hmac));
Algorithms:
- SHA-256, SHA-512 (secure hashing)
- MD5, SHA-1 (deprecated for security)
- bcrypt, scrypt, PBKDF2 (password hashing)
- HMAC (integrity verification)
β¨ Cryptography Best Practices
π Key Management
- Use cryptographically secure random number generators
- Store keys securely (never in code or version control)
- Rotate keys regularly
- Use different keys for different purposes
- Implement proper key lifecycle management
π Algorithm Selection
- Use AES-256 for symmetric encryption
- Use RSA-2048 or ECC for asymmetric encryption
- Use SHA-256 or higher for hashing
- Avoid deprecated algorithms (MD5, SHA-1, DES)
- Stay updated with current security recommendations
π‘οΈ Secure Implementation
- Use established cryptographic libraries
- Implement proper error handling
- Validate all inputs before processing
- Use constant-time comparison functions
- Implement proper padding schemes
Secure Data Handling
π‘οΈ Data Protection Strategies
Implement comprehensive data protection throughout the data lifecycle.
π₯ Input Validation & Sanitization
Validate and clean all input data
// Input validation library
const validator = require('validator');
// User input validation
function validateUserInput(input) {
const errors = [];
// Email validation
if (!validator.isEmail(input.email)) {
errors.push("Invalid email format");
}
// Password strength
if (!validator.isStrongPassword(input.password, {
minLength: 8,
minLowercase: 1,
minUppercase: 1,
minNumbers: 1,
minSymbols: 1
})) {
errors.push("Password does not meet requirements");
}
// SQL injection prevention
if (/