/* Crypto String Securely Encrypts and decrypts a string using a password */ const IV_BYTE_SIZE = 100 // Size of initialization vector const SALT_BYTE_SIZE = 900 // Size of salt const KEY_BYTE_SIZE = 32 // size of cipher key const AUTH_TAG_SIZE = 16 // Size of authentication tag const crypto = require('crypto') let CryptoString = module.exports = {} CryptoString.encrypt = (password, salt64, rawText) => { const initializationVector = crypto.randomBytes(IV_BYTE_SIZE) const salt = Buffer.from(salt64, 'base64') const key = CryptoString.seasonedPassword(password, salt) const cipher = crypto.createCipheriv('aes-256-gcm', key, initializationVector, { 'authTagLength': AUTH_TAG_SIZE }) let encryptedMessage = cipher.update(rawText) encryptedMessage = Buffer.concat([encryptedMessage, cipher.final()]) return Buffer.concat([initializationVector, encryptedMessage, cipher.getAuthTag()]).toString('base64') } //Decrypt base64 string cipher text, CryptoString.decrypt = (password, salt64, cipherTextString) => { if(!password || !salt64 || !cipherTextString){ return '' } if(password.length == 0 || salt64.length == 0 || cipherTextString == 0){ return '' } let cipherText = Buffer.from(cipherTextString, 'base64') const salt = Buffer.from(salt64, 'base64') const authTag = cipherText.slice(AUTH_TAG_SIZE*-1) const initializationVector = cipherText.slice(0, IV_BYTE_SIZE) const encryptedMessage = cipherText.slice(IV_BYTE_SIZE, AUTH_TAG_SIZE*-1) const key = CryptoString.seasonedPassword(password, salt) const decipher = crypto.createDecipheriv('aes-256-gcm', key, initializationVector, { 'authTagLength': AUTH_TAG_SIZE }) try { decipher.setAuthTag(authTag) let messagetext = decipher.update(encryptedMessage) messagetext = Buffer.concat([messagetext, decipher.final()]).toString('utf8') return messagetext } catch(err) { // console.log(err) return null } } //Salt the password - return {buffer} CryptoString.seasonedPassword = (password, salt) => { return crypto.scryptSync(password, salt, KEY_BYTE_SIZE) } //Create random salt - return {string} CryptoString.createSalt = () => { return crypto.randomBytes(SALT_BYTE_SIZE).toString('base64') } CryptoString.createSmallSalt = () => { return crypto.randomBytes(20).toString('base64') } CryptoString.hash = (hashString) => { return crypto.createHash('sha256').update(hashString).digest() } CryptoString.test = () => { const pp = (title, output) => { console.log('----------------'+title+'----------------') console.log(output) } const password = 'ItsMePasswordio123' const text = '

The genesis of  a new note. Very magical.

Quite a weonderful thing


Weonderful for sheore

' const hashTest = CryptoString.createSalt('password') const salt = CryptoString.createSalt() pp('salt',salt.length) const seasonPass = CryptoString.seasonedPassword(password, salt) const cipherText = CryptoString.encrypt(password, salt, text) const decipheredText = CryptoString.decrypt(password, salt, cipherText) pp('Success Decrypt', decipheredText == text ? 'Pass 😁':'Fail' ) const wrongPass = CryptoString.decrypt('Wrong Password', salt, cipherText) pp('Wrong Password', wrongPass === null ? 'Pass':'Fail') const wrongSalt = CryptoString.decrypt(password, 'Wrong Salt', cipherText) pp('Wrong Salt', wrongSalt === null ? 'Pass':'Fail') const wrongCipher = CryptoString.decrypt(password, salt, Buffer.from('Hello there')) pp('Wrong Cipher Text', wrongCipher === null ? 'Pass':'Fail') }