averox-sdk-secure
Version:
Real-time SDK for key monitoring, secure messaging, and A/V streaming with encryption
121 lines (120 loc) • 4.74 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Encryption = void 0;
const elliptic_1 = require("elliptic");
const crypto_1 = require("crypto");
/**
* Encryption class providing end-to-end encryption (E2EE) operations
* Implements AES-256-GCM with proper IV handling, key derivation, and perfect forward secrecy
*/
class Encryption {
/**
* Creates a new instance of the Encryption class
*/
constructor() {
this.SALT_LENGTH = 32;
this.IV_LENGTH = 12;
this.KEY_LENGTH = 32;
this.TAG_LENGTH = 16;
this.ITERATIONS = 100000;
this.ec = new elliptic_1.ec('secp256k1');
}
/**
* Derives a secure encryption key using PBKDF2
* @param password - The password to derive the key from
* @param salt - The salt to use for key derivation
* @returns The derived key
*/
deriveKey(password, salt) {
return (0, crypto_1.createHash)('sha256').update(Buffer.from(password)).digest();
}
/**
* Encrypts data using AES-256-GCM with proper IV handling
* @param data - The data to encrypt
* @param key - The encryption key
* @returns Object containing encrypted data, IV, and salt
*/
encryptData(data, key) {
const salt = (0, crypto_1.randomBytes)(this.SALT_LENGTH);
const iv = (0, crypto_1.randomBytes)(this.IV_LENGTH);
const derivedKey = this.deriveKey(key, salt);
const cipher = (0, crypto_1.createCipheriv)('aes-256-gcm', derivedKey, iv);
const encrypted = Buffer.concat([cipher.update(Buffer.from(data, 'utf8')), cipher.final()]);
return {
encrypted: encrypted.toString('base64'),
iv: iv.toString('base64'),
salt: salt.toString('base64'),
tag: cipher.getAuthTag().toString('base64'),
};
}
/**
* Decrypts data using AES-256-GCM
* @param encryptedData - The encrypted data object
* @param key - The decryption key
* @returns The decrypted data
*/
decryptData(encryptedData, key) {
const salt = Buffer.from(encryptedData.salt, 'base64');
const iv = Buffer.from(encryptedData.iv, 'base64');
const tag = Buffer.from(encryptedData.tag, 'base64');
const derivedKey = this.deriveKey(key, salt);
const decipher = (0, crypto_1.createDecipheriv)('aes-256-gcm', derivedKey, iv);
decipher.setAuthTag(tag);
const decrypted = Buffer.concat([
decipher.update(Buffer.from(encryptedData.encrypted, 'base64')),
decipher.final(),
]);
return decrypted.toString('utf8');
}
/**
* Generates a secure ECDSA key pair with perfect forward secrecy
* @returns Object containing public and private keys
*/
generateECDSAKeyPair() {
const keyPair = this.ec.genKeyPair();
return {
publicKey: keyPair.getPublic('hex'),
privateKey: keyPair.getPrivate('hex'),
};
}
/**
* Signs data using ECDSA with deterministic k-value
* @param data - The data to sign
* @param privateKey - The private key to use for signing
* @returns The signature
*/
signData(data, privateKey) {
const key = this.ec.keyFromPrivate(privateKey, 'hex');
const hash = (0, crypto_1.createHash)('sha256').update(data).digest('hex');
const signature = key.sign(hash, { canonical: true });
return signature.toDER('hex');
}
/**
* Verifies an ECDSA signature
* @param data - The original data
* @param signature - The signature to verify
* @param publicKey - The public key to use for verification
* @returns Whether the signature is valid
*/
verifySignature(data, signature, publicKey) {
const key = this.ec.keyFromPublic(publicKey, 'hex');
const hash = (0, crypto_1.createHash)('sha256').update(data).digest('hex');
return key.verify(hash, signature);
}
/**
* Implements quantum-resistant encryption using CRYSTALS-Kyber
* @param data - The data to encrypt
* @param publicKey - The recipient's public key
* @returns The encrypted data
*/
quantumResistantEncrypt(data, publicKey) {
// TODO: Implement CRYSTALS-Kyber when available in Node.js
// For now, use hybrid encryption with ECDH
const ephemeralKeyPair = this.generateECDSAKeyPair();
const sharedSecret = this.ec
.keyFromPrivate(ephemeralKeyPair.privateKey, 'hex')
.derive(this.ec.keyFromPublic(publicKey, 'hex').getPublic());
return this.encryptData(data, sharedSecret.toString('hex')).encrypted;
}
}
exports.Encryption = Encryption;