Skip to content
Snippets Groups Projects
CryptoServiceNode.js 4.13 KiB
Newer Older
  • Learn to ignore specific revisions
  • Igor Markin's avatar
    Igor Markin committed
    "use strict";
    
    Igor Markin's avatar
    Igor Markin committed
    // All functions are async in order to be compatible with the ICryptoService API
    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    
    Igor Markin's avatar
    Igor Markin committed
    Object.defineProperty(exports, "__esModule", { value: true });
    const crypto = require("crypto");
    
    const common_1 = require("../../utils/common");
    
    Igor Markin's avatar
    Igor Markin committed
    const AES_GCM_ALGO = "aes-256-gcm";
    
    Igor Markin's avatar
    Igor Markin committed
    const encryptAESGCM = (data) => __awaiter(void 0, void 0, void 0, function* () {
    
    Igor Markin's avatar
    Igor Markin committed
        const key = crypto.randomBytes(32);
        const iv = crypto.randomBytes(12);
        const cipher = crypto.createCipheriv(AES_GCM_ALGO, key, iv);
        const encrypted = cipher.update(data, "utf8");
        cipher.final();
        const authTag = cipher.getAuthTag();
        const encryptedWithTag = Buffer.concat([
            Buffer.from(encrypted),
            Buffer.from(authTag),
        ]);
        return {
            key: key.buffer,
            iv: iv.buffer,
            data: encryptedWithTag,
        };
    
    Igor Markin's avatar
    Igor Markin committed
    });
    const decryptAESGCM = (data, key, iv) => __awaiter(void 0, void 0, void 0, function* () {
    
    Igor Markin's avatar
    Igor Markin committed
        const decipher = crypto.createDecipheriv(AES_GCM_ALGO, Buffer.from(key), Buffer.from(iv));
        const authTag = data.slice(data.byteLength - 16, data.byteLength);
        const encrypted = data.slice(0, data.byteLength - 16);
    
        let str = decipher.update(common_1.arrayBufferToBase64(encrypted), "base64", "utf8");
    
    Igor Markin's avatar
    Igor Markin committed
        decipher.setAuthTag(Buffer.from(authTag));
        str += decipher.final("utf8");
        return str;
    
    Igor Markin's avatar
    Igor Markin committed
    });
    const generateRSAKeys = () => __awaiter(void 0, void 0, void 0, function* () {
    
    Igor Markin's avatar
    Igor Markin committed
        const { privateKey, publicKey } = crypto.generateKeyPairSync("rsa", {
            modulusLength: 4096,
            publicKeyEncoding: {
                type: "spki",
                format: "pem",
            },
            privateKeyEncoding: {
                type: "pkcs8",
                format: "pem",
            },
        });
        return {
            publicKeyPEM: publicKey,
            privateKeyPEM: privateKey,
        };
    
    Igor Markin's avatar
    Igor Markin committed
    });
    const encryptRSA = (publicKeyPEM, data) => __awaiter(void 0, void 0, void 0, function* () {
    
    Igor Markin's avatar
    Igor Markin committed
        const encryptedData = crypto.publicEncrypt({
            key: publicKeyPEM,
            padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
            oaepHash: "sha256",
        }, 
        // We convert the data string to a buffer using `Buffer.from`
        Buffer.from(data));
        return encryptedData.buffer;
    
    Igor Markin's avatar
    Igor Markin committed
    });
    const decryptRSA = (privateKeyPEM, data) => __awaiter(void 0, void 0, void 0, function* () {
    
    Igor Markin's avatar
    Igor Markin committed
        const encryptedData = crypto.privateDecrypt({
            key: privateKeyPEM,
            padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
            oaepHash: "sha256",
        }, 
        // We convert the data string to a buffer using `Buffer.from`
        Buffer.from(data));
        return encryptedData.buffer;
    
    Igor Markin's avatar
    Igor Markin committed
    });
    const signRSA = (privateKeyPEM, data) => __awaiter(void 0, void 0, void 0, function* () {
    
    Igor Markin's avatar
    Igor Markin committed
        const sign = crypto.createSign("SHA256");
        sign.update(Buffer.from(data));
        sign.end();
        return sign.sign(privateKeyPEM).buffer;
    
    Igor Markin's avatar
    Igor Markin committed
    });
    const SHA256 = (string) => __awaiter(void 0, void 0, void 0, function* () {
    
    Igor Markin's avatar
    Igor Markin committed
        return crypto.createHash("sha256").update(string, "utf8").digest();
    
    Igor Markin's avatar
    Igor Markin committed
    });
    const verifyRSASignature = (publicKeyPEM, data, signature) => __awaiter(void 0, void 0, void 0, function* () {
    
    Igor Markin's avatar
    Igor Markin committed
        const verify = crypto.createVerify("SHA256");
        verify.update(Buffer.from(data));
        verify.end();
        const publicKey = crypto.createPublicKey(Buffer.from(publicKeyPEM, "utf-8"));
        return verify.verify(publicKey, Buffer.from(signature));
    
    Igor Markin's avatar
    Igor Markin committed
    });
    
    Igor Markin's avatar
    Igor Markin committed
    const implementation = {
        encryptAESGCM,
        decryptAESGCM,
        generateRSAKeys,
        encryptRSA,
        decryptRSA,
    
    Igor Markin's avatar
    Igor Markin committed
        SHA256,
        signRSA,
        verifyRSASignature,
    
    Igor Markin's avatar
    Igor Markin committed
    };
    exports.default = implementation;