UNPKG

easymina

Version:

![CircleCI](https://img.shields.io/circleci/build/github/EasyMina/easyMina/main)

181 lines (143 loc) 5.28 kB
import crypto from 'crypto' import { printMessages } from './../helpers/mixed.mjs' export class Encryption { #config #secret constructor() { this.#config = { 'algorithm': 'aes-256-cbc', 'secret': { 'prefix': 'EA', 'totalLength': 40, 'charSet': 'abcdefghijklmnopqrstuvwxyzZ0123456789', 'regex': /^EA(?=.*[a-z])(?=.*\d).{40,}$/, 'description': 'Allowed are strings that begin with "EA" encompass at least one letter, include at least one digit, and have a length of at least 42 characters.' } } return true } createSecretValue() { let str = null let tries = 0 let loop = true while( loop ) { str = new Array( this.#config['secret']['totalLength'] ) .fill( '' ) .reduce( ( acc, a, index ) => { const randomIndex = crypto.randomInt( 0, this.#config['secret']['charSet'].length ) acc += this.#config['secret']['charSet'] .charAt( randomIndex ) return acc }, this.#config['secret']['prefix'] ) const [ m, c ] = this.validateSecret( { 'secret': str } ) m.length === 0 ? loop = false : loop = true tries ++ } return str } setSecret( { secret, secure=true } ) { if( secure ) { const [ messages, comments ] = this.validateSecret( { secret } ) printMessages( { messages, comments } ) } this.#secret = { 'string': secret, 'digest': null } const hash = crypto.createHash( 'sha256' ) hash.update( this.#secret['string'] ) this.#secret['digest'] = hash.digest() return this } encrypt( { text, secure=true } ) { if( secure ) { const [ messages, comments ] = this.validateSecret( { 'secret': this.#secret['string'] } ) printMessages( { messages, comments } ) } const iv = crypto.randomBytes( 16 ) const cipher = crypto.createCipheriv( this.#config['algorithm'], this.#secret['digest'], iv ) const encrypted = Buffer.concat( [ cipher.update( `${text}` ), cipher.final() ] ) const content = encrypted .toString( 'hex' ) const result = { 'iv': iv.toString('hex'), 'content': content } return result } decrypt( { hash, secure } ) { if( secure ) { const [ messages, comments ] = this.validateSecret( { 'secret': this.#secret['string'] } ) printMessages( { messages, comments } ) } const decipher = crypto.createDecipheriv( this.#config['algorithm'], this.#secret['digest'], Buffer.from( hash['iv'], 'hex' ) ) let decrypted try { decrypted = Buffer.concat( [ decipher.update( Buffer.from( hash['content'], 'hex' ) ), decipher.final() ] ) } catch( e ) { console.log( 'Decryption raised an error. Please check your secret phrase.' ) process.exit( 1 ) } return decrypted.toString() } encryptCredential( { credential } ) { const [ messages, comments ] = this.validateSecret( { 'secret': this.#secret['string'] } ) printMessages( { messages, comments } ) const result = JSON.parse( JSON.stringify( credential ) ) if( !Object.hasOwn( result['header'], 'encrypt' ) ) { console.log( 'account does not have a header property "encrypt".' ) process.exit( 1 ) } else if( typeof result['header']['encrypt'] !== 'boolean' ) { console.log( 'account property "encrypt" is not type of boolean.' ) process.exit( 1 ) } else if( result['header']['encrypt'] ) { result['body'] = this.encrypt( { 'text': JSON.stringify( result['body'] ) } ) } return result } decryptCredential( { credential } ) { const [ messages, comments ] = this.validateSecret( { 'secret': this.#secret['string'] } ) printMessages( { messages, comments } ) if( credential['header']['encrypt'] ) { credential['body'] = JSON.parse( this.decrypt( { 'hash': credential['body'] } ) ) } return credential } validateSecret( { secret } ) { const messages = [] const comments = [] if( typeof secret !== 'string' ) { messages.push( `Secret is not type of string.` ) } else { const test = this.#config['secret']['regex'] .test( secret ) if( !test ) { messages.push( `Secret has not a valid pattern. ${this.#config['secret']['description']}`) } } return [ messages, comments ] } }