UNPKG

versa

Version:

Module to provide encryption/decryption profiles.

212 lines (165 loc) 4.82 kB
'use strict'; var CRYPTO = require('crypto'); function VersaApi( opts ){ if(!(this instanceof VersaApi)) return new VersaApi(opts); var self = this; /* Dereference and free our `opts` // argument before being bound and // passed around (Number, substring.) */ opts = (typeof opts === 'object') ? opts : {}; self.padding = (typeof opts.padding === 'number') ? Number(opts.padding) : 512; self.padding = (self.padding >= 1) ? Math.floor(self.padding) : 0; self.size = (typeof opts.size === 'number') ? Number(opts.size) : 2048; self.size = (self.size >= 16) ? Math.floor(self.size) : 16; self.algorithm = (typeof opts.algorithm === 'string') ? opts.algorithm.substring(0) : 'aes-256-cbc'; VersaApiPassword.call(self,opts); self.decrypt = function VersaApiDecrypt( data ){ var decipher = CRYPTO.createDecipher(self.algorithm,self.password.toString('binary')); if( data === null || data === undefined ){ return decipher; } else{ data = [decipher.update(data), decipher.final()]; return Buffer.concat(data,data[0].length + data[1].length); } }; self.encrypt = function VersaApiEncrypt( data ){ var cipher = CRYPTO.createCipher(self.algorithm,self.password.toString('binary')); if( data === null || data === undefined ){ return cipher; } else{ data = [cipher.update(data), cipher.final()]; return Buffer.concat(data,data[0].length + data[1].length); } }; self.hide = function VersaApiHide( data ){ var bytes; var padding = (self.padding > 0) ? self.padding : 512; var isVersaBuffer = false; if( typeof data === 'string' || Buffer.isBuffer(data) || ( (isVersaBuffer = VersaApiIsBuffer(data)) && isVersaBuffer === true ) ){ data = new Buffer(isVersaBuffer ? data.data : data); bytes = new Buffer(data.length.toString() + "#"); padding = new Buffer(CRYPTO.randomBytes((padding - ((data.length + bytes.length) % padding)))) return self.encrypt(Buffer.concat([ bytes, data, padding ],data.length + bytes.length + padding.length)); } else return false; }; self.profile = function VersaApiProfile( ){ return { 'algorithm': self.algorithm, 'padding': self.padding, 'password': self.password, 'size': self.size }; }; self.show = function VersaApiShow( data ){ var bytes; var index = 0; var isVersaBuffer = false; if( typeof data === 'string' || Buffer.isBuffer(data) || ( (isVersaBuffer = VersaApiIsBuffer(data)) && isVersaBuffer === true ) ){ data = self.decrypt(isVersaBuffer ? data.data : data); while(data.toString('utf-8',index,(index + 1)) !== "#") index++; bytes = parseFloat(data.slice(0,index)); index++; if((data.length - index) < bytes) return false; return data.slice(index,(index + bytes)); } else return false; }; self.json = function VersaApiJson( ){ return JSON.stringify(self.profile()); }; return self; } function VersaApiPassword( opts ){ /* If the provided password is a // buffer, then make a copy of it. */ if(Buffer.isBuffer(opts.password)) this.password = new Buffer(opts.password); /* If the provided password is from // a JSON parsed string, then make // a buffer out of it. */ else if(VersaApiIsBuffer(opts.password)) this.password = new Buffer(opts.password.data); /* If the provided password is a // string, then make a copy of it. */ else if( typeof opts.password === 'string' && opts.password.length > 0 ){ this.password = opts.password.substring(0); } /* If the provided password met // none of the other conditions, // then create a random one. */ else this.password = CRYPTO.randomBytes(this.size); } function VersaApiIsBuffer( data ){ return ( typeof data === 'object' && data !== null && typeof data.type === 'string' && typeof data.data === 'object' && data.type === 'Buffer' && Array.isArray(data.data) ); } module.exports = VersaApi;