Skip to main content

Cryptography Tutorial

Overview​

Cryptography is the practice of secure communication in the presence of third parties. This tutorial covers fundamental cryptographic concepts, modern algorithms, and practical implementation for application security.

Cryptographic Fundamentals​

Hash Functions​

Cryptographic Hash Properties:

  • Deterministic: Same input always produces same output
  • Fixed Output Size: Hash output has fixed length regardless of input size
  • Avalanche Effect: Small input change causes large output change
  • One-Way: Computationally infeasible to reverse
  • Collision Resistant: Hard to find two inputs with same hash
const crypto = require('crypto');

class HashingService {
// SHA-256 hashing
static sha256(data) {
return crypto.createHash('sha256').update(data).digest('hex');
}

// SHA-3 hashing (more recent standard)
static sha3(data) {
return crypto.createHash('sha3-256').update(data).digest('hex');
}

// BLAKE2b hashing (faster than SHA-2)
static blake2b(data) {
return crypto.createHash('blake2b512').update(data).digest('hex');
}

// File integrity verification
static async verifyFileIntegrity(filePath, expectedHash) {
const fs = require('fs').promises;
const fileBuffer = await fs.readFile(filePath);
const actualHash = this.sha256(fileBuffer);
return actualHash === expectedHash;
}

// Merkle tree implementation for data integrity
static buildMerkleTree(data) {
if (data.length === 0) return null;
if (data.length === 1) return this.sha256(data[0]);

const tree = [];
let currentLevel = data.map(item => this.sha256(item));

while (currentLevel.length > 1) {
tree.push([...currentLevel]);
const nextLevel = [];

for (let i = 0; i < currentLevel.length; i += 2) {
const left = currentLevel[i];
const right = currentLevel[i + 1] || left; // Duplicate last if odd count
nextLevel.push(this.sha256(left + right));
}

currentLevel = nextLevel;
}

return {
root: currentLevel[0],
tree: tree
};
}

// HMAC (Hash-based Message Authentication Code)
static hmac(message, key, algorithm = 'sha256') {
return crypto.createHmac(algorithm, key).update(message).digest('hex');
}

// Time-safe string comparison to prevent timing attacks
static constantTimeCompare(a, b) {
if (a.length !== b.length) {
return false;
}

let result = 0;
for (let i = 0; i < a.length; i++) {
result |= a.charCodeAt(i) ^ b.charCodeAt(i);
}

return result === 0;
}
}

// Usage examples
const data = "Hello, World!";
const hash = HashingService.sha256(data);
console.log(`SHA-256: ${hash}`);

// HMAC for message authentication
const message = "Important message";
const secretKey = "my-secret-key";
const signature = HashingService.hmac(message, secretKey);
console.log(`HMAC: ${signature}`);

// Verify HMAC
const receivedSignature = "received-hmac-value";
const isValid = HashingService.constantTimeCompare(signature, receivedSignature);
console.log(`HMAC Valid: ${isValid}`);

Symmetric Encryption​

Advanced Encryption Standard (AES):

const crypto = require('crypto');

class SymmetricEncryption {
constructor() {
this.algorithm = 'aes-256-gcm';
this.keyLength = 32; // 256 bits
this.ivLength = 16; // 128 bits
}

// Generate cryptographically secure random key
generateKey() {
return crypto.randomBytes(this.keyLength);
}

// Encrypt data with AES-256-GCM
encrypt(plaintext, key) {
if (!Buffer.isBuffer(key) || key.length !== this.keyLength) {
throw new Error('Key must be 32 bytes for AES-256');
}

const iv = crypto.randomBytes(this.ivLength);
const cipher = crypto.createCipher(this.algorithm, key);
cipher.setAAD(Buffer.from('authenticated-data')); // Additional authenticated data

let ciphertext = cipher.update(plaintext, 'utf8', 'hex');
ciphertext += cipher.final('hex');

const authTag = cipher.getAuthTag();

return {
ciphertext: ciphertext,
iv: iv.toString('hex'),
authTag: authTag.toString('hex')
};
}

// Decrypt data with AES-256-GCM
decrypt(encryptedData, key) {
if (!Buffer.isBuffer(key) || key.length !== this.keyLength) {
throw new Error('Key must be 32 bytes for AES-256');
}

const decipher = crypto.createDecipher(this.algorithm, key);
decipher.setAAD(Buffer.from('authenticated-data'));
decipher.setAuthTag(Buffer.from(encryptedData.authTag, 'hex'));

let plaintext = decipher.update(encryptedData.ciphertext, 'hex', 'utf8');
plaintext += decipher.final('utf8');

return plaintext;
}

// Key derivation using PBKDF2
deriveKeyFromPassword(password, salt, iterations = 100000) {
if (!salt) {
salt = crypto.randomBytes(16);
}

const key = crypto.pbkdf2Sync(password, salt, iterations, this.keyLength, 'sha256');

return {
key: key,
salt: salt,
iterations: iterations
};
}

// Key derivation using scrypt (more secure, slower)
deriveKeyWithScrypt(password, salt, options = {}) {
if (!salt) {
salt = crypto.randomBytes(16);
}

const defaultOptions = {
N: 16384, // Cost parameter
r: 8, // Block size
p: 1, // Parallelization
maxmem: 32 * 1024 * 1024 // 32 MB
};

const scryptOptions = { ...defaultOptions, ...options };
const key = crypto.scryptSync(password, salt, this.keyLength, scryptOptions);

return {
key: key,
salt: salt,
options: scryptOptions
};
}

// Encrypt file
async encryptFile(inputPath, outputPath, key) {
const fs = require('fs').promises;
const inputData = await fs.readFile(inputPath);
const encrypted = this.encrypt(inputData, key);

const encryptedFile = {
...encrypted,
originalName: require('path').basename(inputPath),
timestamp: new Date().toISOString()
};

await fs.writeFile(outputPath, JSON.stringify(encryptedFile));
return encrypted;
}

// Decrypt file
async decryptFile(inputPath, outputPath, key) {
const fs = require('fs').promises;
const encryptedFile = JSON.parse(await fs.readFile(inputPath, 'utf8'));
const decrypted = this.decrypt(encryptedFile, key);

await fs.writeFile(outputPath, decrypted);
return decrypted;
}
}

// Usage example
const aes = new SymmetricEncryption();

// Generate or derive key
const password = "user-password";
const keyData = aes.deriveKeyWithScrypt(password, null);

// Encrypt sensitive data
const sensitiveData = "Credit card number: 4532-1234-5678-9012";
const encrypted = aes.encrypt(sensitiveData, keyData.key);
console.log('Encrypted:', encrypted);

// Decrypt data
try {
const decrypted = aes.decrypt(encrypted, keyData.key);
console.log('Decrypted:', decrypted);
} catch (error) {
console.error('Decryption failed:', error.message);
}

Asymmetric Encryption​

RSA and Elliptic Curve Cryptography:

const crypto = require('crypto');

class AsymmetricEncryption {
// Generate RSA key pair
generateRSAKeyPair(keySize = 2048) {
return crypto.generateKeyPairSync('rsa', {
modulusLength: keySize,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem',
cipher: 'aes-256-cbc',
passphrase: process.env.PRIVATE_KEY_PASSPHRASE
}
});
}

// Generate Elliptic Curve key pair (more efficient)
generateECKeyPair(curve = 'secp256k1') {
return crypto.generateKeyPairSync('ec', {
namedCurve: curve,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem',
cipher: 'aes-256-cbc',
passphrase: process.env.PRIVATE_KEY_PASSPHRASE
}
});
}

// RSA encryption (for small data only)
encryptRSA(data, publicKey) {
return crypto.publicEncrypt({
key: publicKey,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: 'sha256'
}, Buffer.from(data)).toString('base64');
}

// RSA decryption
decryptRSA(encryptedData, privateKey, passphrase) {
return crypto.privateDecrypt({
key: privateKey,
passphrase: passphrase,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: 'sha256'
}, Buffer.from(encryptedData, 'base64')).toString();
}

// Hybrid encryption (RSA + AES for large data)
hybridEncrypt(data, publicKey) {
// Generate random AES key
const aesKey = crypto.randomBytes(32);
const aes = new SymmetricEncryption();

// Encrypt data with AES
const encryptedData = aes.encrypt(data, aesKey);

// Encrypt AES key with RSA
const encryptedKey = this.encryptRSA(aesKey.toString('base64'), publicKey);

return {
encryptedKey: encryptedKey,
encryptedData: encryptedData
};
}

// Hybrid decryption
hybridDecrypt(hybridData, privateKey, passphrase) {
// Decrypt AES key with RSA
const aesKeyBase64 = this.decryptRSA(hybridData.encryptedKey, privateKey, passphrase);
const aesKey = Buffer.from(aesKeyBase64, 'base64');

// Decrypt data with AES
const aes = new SymmetricEncryption();
return aes.decrypt(hybridData.encryptedData, aesKey);
}

// Digital signatures
sign(data, privateKey, passphrase, algorithm = 'sha256') {
const sign = crypto.createSign(algorithm);
sign.update(data);

return sign.sign({
key: privateKey,
passphrase: passphrase
}, 'base64');
}

// Verify digital signature
verify(data, signature, publicKey, algorithm = 'sha256') {
const verify = crypto.createVerify(algorithm);
verify.update(data);

return verify.verify(publicKey, signature, 'base64');
}

// Elliptic Curve Digital Signature Algorithm (ECDSA)
signECDSA(data, privateKey, passphrase) {
const sign = crypto.createSign('sha256');
sign.update(data);

return sign.sign({
key: privateKey,
passphrase: passphrase,
dsaEncoding: 'der'
}, 'base64');
}

verifyECDSA(data, signature, publicKey) {
const verify = crypto.createVerify('sha256');
verify.update(data);

return verify.verify({
key: publicKey,
dsaEncoding: 'der'
}, signature, 'base64');
}
}

// Key management example
class KeyManager {
constructor() {
this.asymmetric = new AsymmetricEncryption();
}

async generateAndStoreKeys() {
// Generate key pairs
const rsaKeys = this.asymmetric.generateRSAKeyPair(2048);
const ecKeys = this.asymmetric.generateECKeyPair('secp256k1');

// Store keys securely (in production, use a key management service)
const fs = require('fs').promises;

await fs.writeFile('keys/rsa-public.pem', rsaKeys.publicKey);
await fs.writeFile('keys/rsa-private.pem', rsaKeys.privateKey);
await fs.writeFile('keys/ec-public.pem', ecKeys.publicKey);
await fs.writeFile('keys/ec-private.pem', ecKeys.privateKey);

return { rsaKeys, ecKeys };
}

async loadKeys() {
const fs = require('fs').promises;

return {
rsaPublic: await fs.readFile('keys/rsa-public.pem', 'utf8'),
rsaPrivate: await fs.readFile('keys/rsa-private.pem', 'utf8'),
ecPublic: await fs.readFile('keys/ec-public.pem', 'utf8'),
ecPrivate: await fs.readFile('keys/ec-private.pem', 'utf8')
};
}

// Key rotation
async rotateKeys(oldPrivateKey, passphrase) {
// Generate new key pair
const newKeys = this.asymmetric.generateRSAKeyPair();

// Sign new public key with old private key (for verification)
const signature = this.asymmetric.sign(
newKeys.publicKey,
oldPrivateKey,
passphrase
);

return {
...newKeys,
previousKeySignature: signature
};
}
}

Certificate Management and PKI​

Public Key Infrastructure Implementation:

const forge = require('node-forge');

class CertificateManager {
// Generate self-signed certificate
generateSelfSignedCertificate(keyPair, attributes) {
const cert = forge.pki.createCertificate();

cert.publicKey = keyPair.publicKey;
cert.serialNumber = '01';
cert.validity.notBefore = new Date();
cert.validity.notAfter = new Date();
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);

const attrs = attributes || [
{ name: 'countryName', value: 'US' },
{ name: 'organizationName', value: 'My Organization' },
{ name: 'commonName', value: 'localhost' }
];

cert.setSubject(attrs);
cert.setIssuer(attrs);

// Add extensions
cert.setExtensions([
{
name: 'basicConstraints',
cA: true
},
{
name: 'keyUsage',
keyCertSign: true,
digitalSignature: true,
nonRepudiation: true,
keyEncipherment: true,
dataEncipherment: true
},
{
name: 'extKeyUsage',
serverAuth: true,
clientAuth: true,
codeSigning: true,
emailProtection: true,
timeStamping: true
},
{
name: 'subjectAltName',
altNames: [
{ type: 2, value: 'localhost' },
{ type: 2, value: '*.localhost' },
{ type: 7, ip: '127.0.0.1' }
]
}
]);

// Sign certificate
cert.sign(keyPair.privateKey, forge.md.sha256.create());

return cert;
}

// Generate Certificate Signing Request (CSR)
generateCSR(keyPair, attributes) {
const csr = forge.pki.createCertificationRequest();

csr.publicKey = keyPair.publicKey;
csr.setSubject(attributes);

// Sign CSR
csr.sign(keyPair.privateKey, forge.md.sha256.create());

return csr;
}

// Verify certificate
verifyCertificate(cert, caCert) {
try {
// Check if certificate is issued by CA
const isValid = caCert.verify(cert);

// Check validity period
const now = new Date();
const isNotExpired = cert.validity.notAfter > now;
const isNotBeforeValid = cert.validity.notBefore <= now;

return {
isValid: isValid && isNotExpired && isNotBeforeValid,
issuedBy: forge.pki.certificateFromPem(caCert).subject.getField('CN')?.value,
subject: cert.subject.getField('CN')?.value,
validFrom: cert.validity.notBefore,
validUntil: cert.validity.notAfter,
fingerprint: forge.md.sha1.create().update(
forge.asn1.toDer(forge.pki.certificateToAsn1(cert)).getBytes()
).digest().toHex()
};
} catch (error) {
return {
isValid: false,
error: error.message
};
}
}

// Certificate chain validation
validateCertificateChain(certChain, trustedCAs) {
const caStore = forge.pki.createCaStore();

// Add trusted CAs to store
trustedCAs.forEach(ca => {
caStore.addCertificate(ca);
});

try {
// Verify certificate chain
forge.pki.verifyCertificateChain(caStore, certChain);
return { isValid: true };
} catch (error) {
return {
isValid: false,
error: error.message
};
}
}

// Extract certificate information
getCertificateInfo(cert) {
const subject = {};
const issuer = {};

cert.subject.attributes.forEach(attr => {
subject[attr.name] = attr.value;
});

cert.issuer.attributes.forEach(attr => {
issuer[attr.name] = attr.value;
});

return {
subject,
issuer,
serialNumber: cert.serialNumber,
validity: {
notBefore: cert.validity.notBefore,
notAfter: cert.validity.notAfter
},
extensions: cert.extensions.map(ext => ({
name: ext.name,
critical: ext.critical,
value: ext.value
})),
fingerprint: {
sha1: forge.md.sha1.create().update(
forge.asn1.toDer(forge.pki.certificateToAsn1(cert)).getBytes()
).digest().toHex(),
sha256: forge.md.sha256.create().update(
forge.asn1.toDer(forge.pki.certificateToAsn1(cert)).getBytes()
).digest().toHex()
}
};
}
}

Key Derivation Functions​

Secure Key Derivation:

const crypto = require('crypto');

class KeyDerivation {
// PBKDF2 (Password-Based Key Derivation Function 2)
static pbkdf2(password, salt, iterations = 100000, keyLength = 32, digest = 'sha256') {
if (!salt) {
salt = crypto.randomBytes(16);
}

const key = crypto.pbkdf2Sync(password, salt, iterations, keyLength, digest);

return {
key: key,
salt: salt,
iterations: iterations,
algorithm: 'PBKDF2',
digest: digest
};
}

// scrypt (more secure than PBKDF2)
static scrypt(password, salt, options = {}) {
if (!salt) {
salt = crypto.randomBytes(16);
}

const defaultOptions = {
N: 16384, // CPU/memory cost parameter
r: 8, // Block size parameter
p: 1, // Parallelization parameter
maxmem: 32 * 1024 * 1024 // 32 MB max memory
};

const scryptOptions = { ...defaultOptions, ...options };
const keyLength = options.keyLength || 32;

const key = crypto.scryptSync(password, salt, keyLength, scryptOptions);

return {
key: key,
salt: salt,
options: scryptOptions,
algorithm: 'scrypt'
};
}

// Argon2 (winner of password hashing competition)
static async argon2(password, salt, options = {}) {
const argon2 = require('argon2');

if (!salt) {
salt = crypto.randomBytes(16);
}

const defaultOptions = {
type: argon2.argon2id,
memoryCost: 2 ** 16, // 64 MB
timeCost: 3,
parallelism: 1,
salt: salt
};

const argon2Options = { ...defaultOptions, ...options };

const hash = await argon2.hash(password, argon2Options);

return {
hash: hash,
salt: salt,
options: argon2Options,
algorithm: 'Argon2id'
};
}

// HKDF (HMAC-based Key Derivation Function)
static hkdf(inputKeyMaterial, salt, info, keyLength = 32, digest = 'sha256') {
if (!salt) {
salt = Buffer.alloc(0); // Empty salt for HKDF
}

// Extract phase
const prk = crypto.createHmac(digest, salt).update(inputKeyMaterial).digest();

// Expand phase
const iterations = Math.ceil(keyLength / crypto.createHash(digest).digest().length);
let t = Buffer.alloc(0);
let okm = Buffer.alloc(0);

for (let i = 1; i <= iterations; i++) {
const hmac = crypto.createHmac(digest, prk);
hmac.update(t);
hmac.update(info || '');
hmac.update(Buffer.from([i]));
t = hmac.digest();
okm = Buffer.concat([okm, t]);
}

return {
key: okm.slice(0, keyLength),
salt: salt,
info: info,
algorithm: 'HKDF',
digest: digest
};
}

// Key stretching for additional security
static stretchKey(key, stretching = 1000) {
let stretched = key;

for (let i = 0; i < stretching; i++) {
stretched = crypto.createHash('sha256').update(stretched).digest();
}

return stretched;
}

// Derive multiple keys from master key
static deriveMultipleKeys(masterKey, purposes, keyLength = 32) {
const keys = {};

purposes.forEach(purpose => {
keys[purpose] = this.hkdf(
masterKey,
Buffer.from(purpose, 'utf8'),
Buffer.from(`key-derivation-${purpose}`, 'utf8'),
keyLength
).key;
});

return keys;
}
}

// Example usage
async function demonstrateKeyDerivation() {
const password = 'user-strong-password';

// PBKDF2
const pbkdf2Result = KeyDerivation.pbkdf2(password);
console.log('PBKDF2 Key:', pbkdf2Result.key.toString('hex'));

// scrypt
const scryptResult = KeyDerivation.scrypt(password);
console.log('scrypt Key:', scryptResult.key.toString('hex'));

// Argon2
const argon2Result = await KeyDerivation.argon2(password);
console.log('Argon2 Hash:', argon2Result.hash);

// Derive multiple keys from master key
const masterKey = scryptResult.key;
const multipleKeys = KeyDerivation.deriveMultipleKeys(masterKey, [
'encryption',
'authentication',
'database'
]);

console.log('Encryption Key:', multipleKeys.encryption.toString('hex'));
console.log('Auth Key:', multipleKeys.authentication.toString('hex'));
console.log('DB Key:', multipleKeys.database.toString('hex'));
}

Cryptographic Protocols​

Secure Communication Protocols:

class SecureCommunication {
constructor() {
this.sessions = new Map();
}

// Diffie-Hellman Key Exchange
performDHKeyExchange() {
// Generate DH parameters
const alice = crypto.getDiffieHellman('modp14'); // 2048-bit MODP group
const bob = crypto.getDiffieHellman('modp14');

// Generate key pairs
alice.generateKeys();
bob.generateKeys();

// Exchange public keys and compute shared secret
const aliceSecret = alice.computeSecret(bob.getPublicKey());
const bobSecret = bob.computeSecret(alice.getPublicKey());

// Verify both parties have the same shared secret
const sharedSecretMatch = aliceSecret.equals(bobSecret);

return {
sharedSecret: aliceSecret,
isValid: sharedSecretMatch,
alicePublic: alice.getPublicKey(),
bobPublic: bob.getPublicKey()
};
}

// Elliptic Curve Diffie-Hellman (ECDH)
performECDHKeyExchange() {
const alice = crypto.createECDH('secp256k1');
const bob = crypto.createECDH('secp256k1');

// Generate key pairs
alice.generateKeys();
bob.generateKeys();

// Compute shared secrets
const aliceSecret = alice.computeSecret(bob.getPublicKey());
const bobSecret = bob.computeSecret(alice.getPublicKey());

return {
sharedSecret: aliceSecret,
isValid: aliceSecret.equals(bobSecret),
alicePublic: alice.getPublicKey(),
bobPublic: bob.getPublicKey()
};
}

// Secure session establishment
establishSecureSession(sessionId, sharedSecret) {
// Derive session keys from shared secret
const sessionKeys = KeyDerivation.deriveMultipleKeys(sharedSecret, [
'encryption',
'authentication',
'integrity'
]);

const session = {
id: sessionId,
establishedAt: new Date(),
keys: sessionKeys,
messageCounter: 0
};

this.sessions.set(sessionId, session);
return session;
}

// Secure message encryption
encryptMessage(sessionId, message) {
const session = this.sessions.get(sessionId);
if (!session) {
throw new Error('Session not found');
}

const aes = new SymmetricEncryption();

// Encrypt message
const encrypted = aes.encrypt(message, session.keys.encryption);

// Add message authentication code
const mac = crypto.createHmac('sha256', session.keys.authentication)
.update(encrypted.ciphertext)
.digest('hex');

// Increment message counter
session.messageCounter++;

return {
sessionId: sessionId,
messageId: session.messageCounter,
encrypted: encrypted,
mac: mac,
timestamp: new Date().toISOString()
};
}

// Secure message decryption
decryptMessage(encryptedMessage) {
const session = this.sessions.get(encryptedMessage.sessionId);
if (!session) {
throw new Error('Session not found');
}

// Verify message authentication code
const expectedMac = crypto.createHmac('sha256', session.keys.authentication)
.update(encryptedMessage.encrypted.ciphertext)
.digest('hex');

if (expectedMac !== encryptedMessage.mac) {
throw new Error('Message authentication failed');
}

// Decrypt message
const aes = new SymmetricEncryption();
const decrypted = aes.decrypt(encryptedMessage.encrypted, session.keys.encryption);

return {
message: decrypted,
messageId: encryptedMessage.messageId,
sessionId: encryptedMessage.sessionId,
timestamp: encryptedMessage.timestamp
};
}

// Perfect Forward Secrecy - rotate session keys
rotateSessionKeys(sessionId) {
const session = this.sessions.get(sessionId);
if (!session) {
throw new Error('Session not found');
}

// Generate new shared secret using ECDH
const keyExchange = this.performECDHKeyExchange();

// Derive new session keys
const newKeys = KeyDerivation.deriveMultipleKeys(keyExchange.sharedSecret, [
'encryption',
'authentication',
'integrity'
]);

// Update session
session.keys = newKeys;
session.lastRotation = new Date();

return session;
}
}

Cryptographic Best Practices​

Secure Random Number Generation​

class SecureRandom {
// Generate cryptographically secure random bytes
static generateBytes(length) {
return crypto.randomBytes(length);
}

// Generate secure random integers
static generateInt(min, max) {
const range = max - min + 1;
const bytesNeeded = Math.ceil(Math.log2(range) / 8);
let randomValue;

do {
randomValue = crypto.randomBytes(bytesNeeded).readUIntBE(0, bytesNeeded);
} while (randomValue >= Math.floor(2 ** (bytesNeeded * 8) / range) * range);

return min + (randomValue % range);
}

// Generate secure random string
static generateString(length, charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') {
let result = '';
for (let i = 0; i < length; i++) {
result += charset.charAt(this.generateInt(0, charset.length - 1));
}
return result;
}

// Generate UUID v4
static generateUUID() {
return crypto.randomUUID();
}

// Test randomness quality (basic statistical tests)
static testRandomness(samples = 10000) {
const bytes = this.generateBytes(samples);
const bitCounts = [0, 0];

// Count 0s and 1s
for (let i = 0; i < bytes.length; i++) {
for (let bit = 0; bit < 8; bit++) {
bitCounts[(bytes[i] >> bit) & 1]++;
}
}

const totalBits = samples * 8;
const ratio = bitCounts[1] / totalBits;
const isBalanced = Math.abs(ratio - 0.5) < 0.01; // Within 1% of 50/50

return {
totalBits,
ones: bitCounts[1],
zeros: bitCounts[0],
ratio,
isBalanced
};
}
}

Timing Attack Prevention​

class TimingSafeOperations {
// Constant-time string comparison
static constantTimeEqual(a, b) {
if (a.length !== b.length) {
return false;
}

let result = 0;
for (let i = 0; i < a.length; i++) {
result |= a.charCodeAt(i) ^ b.charCodeAt(i);
}

return result === 0;
}

// Constant-time buffer comparison
static constantTimeBufferEqual(a, b) {
return crypto.timingSafeEqual(a, b);
}

// Add artificial delay to prevent timing analysis
static async addRandomDelay(minMs = 50, maxMs = 200) {
const delay = SecureRandom.generateInt(minMs, maxMs);
return new Promise(resolve => setTimeout(resolve, delay));
}

// Constant-time password verification
static async verifyPasswordConstantTime(inputPassword, storedHash) {
// Always perform the same operations regardless of early failures
const startTime = process.hrtime.bigint();

let isValid = false;
try {
isValid = await bcrypt.compare(inputPassword, storedHash);
} catch (error) {
// Continue with timing normalization even on error
}

// Normalize timing to prevent timing attacks
const elapsedTime = process.hrtime.bigint() - startTime;
const minTime = BigInt(50_000_000); // 50ms in nanoseconds

if (elapsedTime < minTime) {
const remainingTime = Number(minTime - elapsedTime) / 1_000_000; // Convert to ms
await new Promise(resolve => setTimeout(resolve, remainingTime));
}

return isValid;
}
}

Cryptographic Compliance and Standards​

class CryptoCompliance {
// FIPS 140-2 compliant algorithms
static getFIPSApprovedAlgorithms() {
return {
symmetricEncryption: ['AES-128', 'AES-192', 'AES-256'],
asymmetricEncryption: ['RSA-2048', 'RSA-3072', 'RSA-4096'],
digitalSignatures: ['RSA-PSS', 'ECDSA'],
hashFunctions: ['SHA-224', 'SHA-256', 'SHA-384', 'SHA-512'],
keyDerivation: ['PBKDF2', 'HKDF'],
messageAuth: ['HMAC-SHA-256', 'HMAC-SHA-384', 'HMAC-SHA-512']
};
}

// Validate cryptographic configuration
static validateCryptoConfig(config) {
const approved = this.getFIPSApprovedAlgorithms();
const violations = [];

if (!approved.symmetricEncryption.includes(config.symmetricAlgorithm)) {
violations.push(`Non-approved symmetric algorithm: ${config.symmetricAlgorithm}`);
}

if (config.keyLength < 2048) {
violations.push(`Key length too short: ${config.keyLength} bits`);
}

if (!approved.hashFunctions.includes(config.hashAlgorithm)) {
violations.push(`Non-approved hash function: ${config.hashAlgorithm}`);
}

return {
isCompliant: violations.length === 0,
violations
};
}

// Generate compliance report
static generateComplianceReport(implementation) {
const report = {
timestamp: new Date().toISOString(),
standards: ['FIPS 140-2', 'NIST SP 800-53'],
algorithms: {},
keyManagement: {},
recommendations: []
};

// Analyze implementation
if (implementation.encryption) {
report.algorithms.encryption = {
algorithm: implementation.encryption.algorithm,
keyLength: implementation.encryption.keyLength,
mode: implementation.encryption.mode,
compliant: this.validateCryptoConfig(implementation.encryption).isCompliant
};
}

// Add recommendations
if (report.algorithms.encryption && !report.algorithms.encryption.compliant) {
report.recommendations.push('Upgrade to FIPS 140-2 approved encryption algorithms');
}

return report;
}
}

Cryptography is fundamental to modern application security. Always use well-established libraries, follow current standards, implement proper key management, and regularly update cryptographic implementations to address new threats and vulnerabilities.

Content Review​

The content in this repository has been reviewed by chevp. Chevp is dedicated to ensuring that the information provided is accurate, relevant, and up-to-date, helping users to learn and implement programming skills effectively.

About the Reviewer​

For more insights and contributions, visit chevp's GitHub profile: chevp's GitHub Profile.