UNPKG

vpn.email

Version:
101 lines (76 loc) 2.63 kB
import * as crypto from 'crypto' export interface packetBuffer { command: number; uuid: string; buffer: Buffer; serial: number } export interface pairConnect { serverListen: string; clientListen: string; } export const encrypt = ( text: string, masterkey ) => { // random initialization vector var iv = crypto.randomBytes ( 12 ); // random salt var salt = crypto.randomBytes ( 64 ); // derive key: 32 byte key length - in assumption the masterkey is a cryptographic and NOT a password there is no need for // a large number of iterations. It may can replaced by HKDF var key = crypto.pbkdf2Sync ( masterkey, salt, 2145, 32, 'sha512' ); // AES 256 GCM Mode var cipher = crypto.createCipheriv ( 'aes-256-gcm', key, iv ); // encrypt the given text var encrypted = Buffer.concat ([ cipher.update ( Buffer.from ( text, 'utf8' )), cipher.final ()]); // extract the auth tag var tag = cipher.getAuthTag (); // generate output return Buffer.concat ([ salt, iv, tag, encrypted ]) } /** * Decrypts text by given key * @param String base64 encoded input data * @param Buffer masterkey * @returns String decrypted (original) text */ export const decrypt = ( data: Buffer, masterkey, CallBack ) => { if ( !data || !data.length ) return CallBack ( new Error('null')) try { // base64 decoding // convert data to buffers var salt = data.slice ( 0, 64 ); var iv = data.slice ( 64, 76 ); var tag = data.slice ( 76, 92 ); var text = data.slice ( 92 ); // derive key using; 32 byte key length var key = crypto.pbkdf2Sync ( masterkey, salt , 2145, 32, 'sha512' ); // AES 256 GCM Mode var decipher = crypto.createDecipheriv ( 'aes-256-gcm', key, iv ); decipher.setAuthTag ( tag ); // encrypt the given text var decrypted = decipher.update ( text ) + decipher.final ( 'utf8' ); return CallBack ( null, decrypted ) } catch ( e ) { return CallBack ( e ) } } export const packetBuffer = ( bit0: number, _serial: number, id: string, buffer: Buffer ) => { const _buffer = new Buffer ( 6 ) _buffer.fill ( 0 ) _buffer.writeUInt8 ( bit0, 0 ) _buffer.writeUInt32BE ( _serial, 1 ) const uuid = new Buffer ( id, 'utf8' ) _buffer.writeUInt8 ( id.length, 5 ) if ( buffer && buffer.length ) return Buffer.concat ([ _buffer, uuid, buffer ]) return Buffer.concat ([ _buffer, uuid ]) } export const openPacket = ( buffer: Buffer ) => { const idLength = buffer.readUInt8 ( 5 ) return { command: buffer.readUInt8 ( 0 ), serial: buffer.readUInt32BE ( 1 ), uuid: buffer.toString ( 'utf8', 6, 6 + idLength ), buffer: buffer.slice ( 6 + idLength ) } }