├── README.md └── src ├── asymmetric-encrypt.js ├── hack.js ├── hash.js ├── hmac.js ├── keypair.js ├── salt.js ├── sign.js └── symmetric-encrypt.js /README.md: -------------------------------------------------------------------------------- 1 | # Node Crypto Examples 2 | 3 | 7 useful examples of the node crypto module. 4 | 5 | - Watch [7 Cryptography Concepts](https://youtu.be/NuyzuNBFWxQ) on YouTube 6 | - Full [Node Crypto Tutorial](https://fireship.io/lessons/node-crypto-examples/) on Fireship 7 | 8 | ## Concepts 9 | 10 | 1. Hash 11 | 1. Salt 12 | 1. HMAC 13 | 1. Symmetric Encryption 14 | 1. Keypairs 15 | 1. Asymmetric Encryption 16 | 1. Signing 17 | 18 | ## Challenge 19 | 20 | Check out the `src/hack.js` file for a challenge. First person to send a pull request with the correct answer wins a T-shirt! -------------------------------------------------------------------------------- /src/asymmetric-encrypt.js: -------------------------------------------------------------------------------- 1 | const { publicEncrypt, privateDecrypt } = require('crypto'); 2 | const { publicKey, privateKey } = require('./keypair'); 3 | 4 | const message = 'the british are coming!' 5 | 6 | const encryptedData = publicEncrypt( 7 | publicKey, 8 | Buffer.from(message) 9 | ); 10 | 11 | 12 | console.log(encryptedData.toString('hex')) 13 | 14 | 15 | const decryptedData = privateDecrypt( 16 | privateKey, 17 | encryptedData 18 | ); 19 | 20 | console.log(decryptedData.toString('utf-8')); -------------------------------------------------------------------------------- /src/hack.js: -------------------------------------------------------------------------------- 1 | ///// Challenge ///// 2 | 3 | // Below is a hash 4 | // Use your hacking skills to crack it! 5 | 6 | const hash = '5e7d28e2cfff93edefb2d15abad07ec5'; 7 | 8 | 9 | // When you figure it out, create a Pull Request on github with value. 10 | // First correct PR wins a Lifetime PRO membership and T-shirt 11 | 12 | ///// ANSWER ///// 13 | 14 | const hacked = 'superhacker'; 15 | 16 | -------------------------------------------------------------------------------- /src/hash.js: -------------------------------------------------------------------------------- 1 | const { createHash } = require('crypto'); 2 | 3 | // Create a string hash 4 | 5 | function hash(input) { 6 | return createHash('sha256').update(input).digest('base64'); 7 | } 8 | 9 | // Compare two hashed passwords 10 | 11 | let password = 'hi-mom!'; 12 | const hash1 = hash(password); 13 | console.log(hash1) 14 | 15 | /// ... some time later 16 | 17 | password = 'hi-mom!'; 18 | const hash2 = hash(password); 19 | const match = hash1 === hash2; 20 | 21 | console.log(match ? '✔️ good password' : '❌ password does not match'); 22 | 23 | -------------------------------------------------------------------------------- /src/hmac.js: -------------------------------------------------------------------------------- 1 | const { createHmac } = require('crypto'); 2 | 3 | const key = 'super-secret!'; 4 | const message = 'boo 👻'; 5 | 6 | const hmac = createHmac('sha256', key).update(message).digest('hex'); 7 | 8 | console.log(hmac); 9 | 10 | const key2 = 'other-password'; 11 | const hmac2 = createHmac('sha256', key2).update(message).digest('hex'); 12 | 13 | console.log(hmac2); 14 | -------------------------------------------------------------------------------- /src/keypair.js: -------------------------------------------------------------------------------- 1 | const { generateKeyPairSync } = require('crypto'); 2 | 3 | const { privateKey, publicKey } = generateKeyPairSync('rsa', { 4 | modulusLength: 2048, // the length of your key in bits 5 | publicKeyEncoding: { 6 | type: 'spki', // recommended to be 'spki' by the Node.js docs 7 | format: 'pem', 8 | }, 9 | privateKeyEncoding: { 10 | type: 'pkcs8', // recommended to be 'pkcs8' by the Node.js docs 11 | format: 'pem', 12 | // cipher: 'aes-256-cbc', 13 | // passphrase: 'top secret' 14 | }, 15 | }); 16 | 17 | // console.log(publicKey); 18 | // console.log(privateKey); 19 | 20 | module.exports = { 21 | privateKey, publicKey 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/salt.js: -------------------------------------------------------------------------------- 1 | const { scryptSync, randomBytes, timingSafeEqual } = require('crypto'); 2 | 3 | function signup(email, password) { 4 | const salt = randomBytes(16).toString('hex'); 5 | const hashedPassword = scryptSync(password, salt, 64).toString('hex'); 6 | 7 | const user = { email, password: `${salt}:${hashedPassword}` } 8 | 9 | users.push(user); 10 | 11 | return user 12 | } 13 | 14 | function login(email, password) { 15 | const user = users.find(v => v.email === email); 16 | 17 | const [salt, key] = user.password.split(':'); 18 | const hashedBuffer = scryptSync(password, salt, 64); 19 | 20 | const keyBuffer = Buffer.from(key, 'hex'); 21 | const match = timingSafeEqual(hashedBuffer, keyBuffer); 22 | 23 | if (match) { 24 | return 'login success!' 25 | } else { 26 | return 'login fail!' 27 | } 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/sign.js: -------------------------------------------------------------------------------- 1 | const { createSign, createVerify } = require('crypto'); 2 | const { publicKey, privateKey } = require('./keypair'); 3 | 4 | const message = 'this data must be signed'; 5 | 6 | /// SIGN 7 | 8 | const signer = createSign('rsa-sha256'); 9 | 10 | signer.update(message); 11 | 12 | const signature = signer.sign(privateKey, 'hex'); 13 | 14 | 15 | /// VERIFY 16 | 17 | const verifier = createVerify('rsa-sha256'); 18 | 19 | verifier.update(message); 20 | 21 | const isVerified = verifier.verify(publicKey, signature, 'hex'); 22 | 23 | console.log(`Verified: ${isVerified}`) 24 | 25 | -------------------------------------------------------------------------------- /src/symmetric-encrypt.js: -------------------------------------------------------------------------------- 1 | const { createCipheriv, randomBytes, createDecipheriv } = require('crypto'); 2 | 3 | /// Cipher 4 | 5 | const message = 'i like turtles'; 6 | const key = randomBytes(32); 7 | const iv = randomBytes(16); 8 | 9 | const cipher = createCipheriv('aes256', key, iv); 10 | 11 | /// Encrypt 12 | 13 | const encryptedMessage = cipher.update(message, 'utf8', 'hex') + cipher.final('hex'); 14 | console.log(`Encrypted: ${encryptedMessage}`); 15 | 16 | /// Decrypt 17 | 18 | const decipher = createDecipheriv('aes256', key, iv); 19 | const decryptedMessage = decipher.update(encryptedMessage, 'hex', 'utf-8') + decipher.final('utf8'); 20 | 21 | console.log(`Deciphered: ${decryptedMessage.toString('utf-8')}`); --------------------------------------------------------------------------------