All files / src/command/dappServer encrypt.js

100% Statements 21/21
100% Branches 3/3
100% Functions 4/4
100% Lines 21/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72          6x 6x 6x   6x                         2x 1x   2x 2x 2x 2x 2x 2x                 1x 1x 1x 1x 1x                         1x 1x 1x               1x          
import Crypto from 'crypto';
import elliptic from 'elliptic';
import { randomId } from '../../utils/utils.js';
import HKDF from './HKDF.js';
 
const defaultEncryptAlgorithm = 'curve25519';
const defaultCipher = 'aes-256-cbc';
const defaultEc = elliptic.ec(defaultEncryptAlgorithm);
 
const keyPairs = {
  [defaultEncryptAlgorithm]: defaultEc.genKeyPair()
};
 
class Encrypt {
  /**
   * Creates an instance of Encrypt.
   * @param {string} algorithm - The algorithm to use for encryption.
   * @param {string} remotePublicKey - The public key of the remote party.
   * @param {string} random - A random string used for key generation.
   * @param {string} [cipher] - The cipher to use for encryption (optional).
   */
  constructor(algorithm, remotePublicKey, random, cipher = defaultCipher) {
    if (!keyPairs[algorithm]) {
      keyPairs[algorithm] = elliptic.ec(algorithm).genKeyPair();
    }
    this.keyPair = keyPairs[algorithm];
    this.cipher = cipher;
    this.remoteKeyPair = elliptic.ec(algorithm).keyFromPublic(remotePublicKey, 'hex');
    this.sharedKey = Buffer.from(this.keyPair.derive(this.remoteKeyPair.getPublic()).toString('hex'), 'hex');
    const hkdf = new HKDF('sha256', Buffer.from(random, 'hex'), this.sharedKey.toString('hex'));
    this.derivedKey = hkdf.expand();
  }
 
  /**
   * Encrypts data using the specified algorithm and shared key.
   * @param {string} data - The data to encrypt.
   * @returns {{ encryptedResult: string, iv: string }} - The encrypted data and initialization vector.
   */
  encrypt(data) {
    const iv = randomId();
    const cipher = Crypto.createCipheriv(this.cipher, this.derivedKey, Buffer.from(iv, 'hex'));
    let encrypted = cipher.update(Buffer.from(data, 'base64'), undefined, 'base64');
    encrypted += cipher.final('base64');
    return {
      encryptedResult: encrypted,
      iv
    };
  }
 
  /**
   * Decrypts data using the specified algorithm and shared key.
   * @param {string} encrypted - The encrypted data to decrypt.
   * @param {string} iv - The initialization vector used during encryption.
   * @returns {string} - The decrypted data.
   */
  decrypt(encrypted, iv) {
    const decipher = Crypto.createDecipheriv(this.cipher, this.derivedKey, Buffer.from(iv, 'hex'));
    const decrypted = Buffer.concat([decipher.update(Buffer.from(encrypted, 'base64')), decipher.final()]).toString('base64');
    return decrypted;
  }
 
  /**
   * Gets the public key of the key pair.
   * @returns {string} - The public key in hexadecimal format.
   */
  getPublicKey() {
    return this.keyPair.getPublic('hex');
  }
}
 
export default Encrypt;