Cryptography protects data by transforming it into a format only intended recipients can understand. It's essential for securing passwords, online transactions, and sensitive communications. Below, you'll learn about encryption, hashing, and using JavaScript to implement them.
Cryptography transforms readable data (plaintext) into an unreadable format (ciphertext). Only authorized parties can reverse the process.
Key Concepts:
Uses the same key for encryption and decryption. The key must be shared securely between sender and receiver. AES is a widely used type of symmetric encryption algorithm that secures data by converting it into an unreadable format. It relies on secret keys and supports 128, 192, or 256-bit key lengths, providing strong protection against unauthorized access. AES is essential for:
Key elements of AES include the key and the Initialization Vector (IV). The key is a secret value shared between parties, determining how data is encrypted and decrypted, and it must always remain confidential. The IV is a random value used alongside the key to ensure that identical plaintext encrypts to different ciphertexts, adding randomness to prevent pattern recognition. While the IV can be public, it must never be reused with the same key. Together, these elements enable AES to effectively counter cyber threats, making it a cornerstone of data security.
AES encrypts data using a shared key and an initialization vector (IV) for added randomness.
const crypto = require('crypto'); const algorithm = 'aes-256-cbc'; const key = crypto.randomBytes(32); const iv = crypto.randomBytes(16); function encrypt(text) { const cipher = crypto.createCipheriv(algorithm, key, iv); let encrypted = cipher.update(text, 'utf8', 'hex'); encrypted += cipher.final('hex'); return { encrypted, iv: iv.toString('hex'), key: key.toString('hex') }; } function decrypt(encrypted, ivHex, keyHex) { const decipher = crypto.createDecipheriv(algorithm, Buffer.from(keyHex, 'hex'), Buffer.from(ivHex, 'hex')); let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } // Usage const message = "Secret Message"; const encryptedData = encrypt(message); console.log("Encrypted:", encryptedData); const decryptedMessage = decrypt(encryptedData.encrypted, encryptedData.iv, encryptedData.key); console.log("Decrypted:", decryptedMessage);
To create a secure encrypted system, asymmetric encryption is often the solution. It uses two keys: a public key for encryption and a private key for decryption. This setup enables secure communication without sharing a single key.
Key Pair Generation
A public-private key pair is generated. The public key is shared openly, while the private key stays confidential.
Encryption
The recipient's public key encrypts the data. Only their private key can decrypt it, keeping the data safe even if intercepted.
Decryption
The recipient decrypts the data using their private key.
const crypto = require('crypto'); const algorithm = 'aes-256-cbc'; const key = crypto.randomBytes(32); const iv = crypto.randomBytes(16); function encrypt(text) { const cipher = crypto.createCipheriv(algorithm, key, iv); let encrypted = cipher.update(text, 'utf8', 'hex'); encrypted += cipher.final('hex'); return { encrypted, iv: iv.toString('hex'), key: key.toString('hex') }; } function decrypt(encrypted, ivHex, keyHex) { const decipher = crypto.createDecipheriv(algorithm, Buffer.from(keyHex, 'hex'), Buffer.from(ivHex, 'hex')); let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } // Usage const message = "Secret Message"; const encryptedData = encrypt(message); console.log("Encrypted:", encryptedData); const decryptedMessage = decrypt(encryptedData.encrypted, encryptedData.iv, encryptedData.key); console.log("Decrypted:", decryptedMessage);
Hashing converts data into a fixed-length, irreversible string (hash). It's commonly used for verifying data integrity and securely storing passwords.
Popular Hashing Algorithms:
Example of Hashing a String in Node.js
const crypto = require('crypto'); // Generate keys const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { modulusLength: 2048 }); const data = "Confidential Data"; // Encrypt const encrypted = crypto.publicEncrypt(publicKey, Buffer.from(data)); console.log("Encrypted:", encrypted.toString('base64')); // Decrypt const decrypted = crypto.privateDecrypt(privateKey, encrypted); console.log("Decrypted:", decrypted.toString());
Feature | Encryption | Hashing | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Two-way (encrypt/decrypt) | One-way | |||||||||||||||
Purpose | Data confidentiality | Data integrity | |||||||||||||||
Reversible | Yes | No | |||||||||||||||
Example | AES, RSA | SHA-256, bcrypt |
In my project Whisper, we used asymmetric encryption to secure anonymous chat messages. Messages are encrypted with the recipient's public key, ensuring only the recipient can decrypt them using their private key.
For client-side React implementation, we used crypto-js for encryption and decryption:
const crypto = require('crypto'); const algorithm = 'aes-256-cbc'; const key = crypto.randomBytes(32); const iv = crypto.randomBytes(16); function encrypt(text) { const cipher = crypto.createCipheriv(algorithm, key, iv); let encrypted = cipher.update(text, 'utf8', 'hex'); encrypted += cipher.final('hex'); return { encrypted, iv: iv.toString('hex'), key: key.toString('hex') }; } function decrypt(encrypted, ivHex, keyHex) { const decipher = crypto.createDecipheriv(algorithm, Buffer.from(keyHex, 'hex'), Buffer.from(ivHex, 'hex')); let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } // Usage const message = "Secret Message"; const encryptedData = encrypt(message); console.log("Encrypted:", encryptedData); const decryptedMessage = decrypt(encryptedData.encrypted, encryptedData.iv, encryptedData.key); console.log("Decrypted:", decryptedMessage);
Decryption uses the private key:
const crypto = require('crypto'); // Generate keys const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { modulusLength: 2048 }); const data = "Confidential Data"; // Encrypt const encrypted = crypto.publicEncrypt(publicKey, Buffer.from(data)); console.log("Encrypted:", encrypted.toString('base64')); // Decrypt const decrypted = crypto.privateDecrypt(privateKey, encrypted); console.log("Decrypted:", decrypted.toString());
Explore Whisper's Code for detailed examples.
Cryptography strengthens data security in applications. Use symmetric encryption like AES for shared-key scenarios and asymmetric encryption for public-private key systems. Hashing ensures data integrity, especially for passwords. Select the right cryptographic approach based on your application's needs.
Read more on Shared Key
Read more on Public Key
Read more on SHA-256
Read more on SHA-3
Read more on MD5
Read more on SHA-1
Read more on Symmetric-encryption
Read more on AES
Thanks for reading, let me know what you think about this and if you would like to see more, if you think i made a mistake or missed something, don't hesitate to comment
The above is the detailed content of Cryptography in JavaScript: A Practical Guide. For more information, please follow other related articles on the PHP Chinese website!