UNPKG

@fioprotocol/fiojs

Version:

FioJS is a Utility SDK for packing, signing and encryption functionality for the FIO blockchain. It is used by the FIO TypeScript SDK

94 lines 3.81 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.checkDecrypt = exports.checkEncrypt = void 0; /** * @module Encryption */ var crypto = __importStar(require("browserify-aes")); var randomBytes = require("randombytes"); var createHmac = require("create-hmac"); var createHash = require("create-hash"); /** * Provides AES-256-CBC encryption and message authentication. The CBC cipher is * used for good platform native compatability. * * @see https://security.stackexchange.com/a/63134 * @see https://security.stackexchange.com/a/20493 * * @arg {Buffer} secret - See PrivateKey.getSharedSecret() * @arg {Buffer} message - plaintext * @arg {Buffer} [IV = randomBytes(16)] - An unpredictable strong random value * is required and supplied by default. Unit tests may provide a static value * to achieve predictable results. * * @throws {Error} IV must be 16 bytes */ function checkEncrypt(secret, message, IV) { var K = createHash("sha512").update(secret).digest(); var Ke = K.slice(0, 32); // Encryption var Km = K.slice(32); // MAC if (IV == null) { IV = randomBytes(16); } else { if (IV.length !== 16) { throw new TypeError("IV must be 16 bytes"); } } // Cipher performs PKCS#5 padded automatically var cipher = crypto.createCipheriv("aes-256-cbc", Ke, IV); var C = Buffer.concat([cipher.update(message), cipher.final()]); // Include in the HMAC input everything that impacts the decryption var M = createHmac("sha256", Km).update(Buffer.concat([IV, C])).digest(); // AuthTag return Buffer.concat([IV, C, M]); } exports.checkEncrypt = checkEncrypt; /** * Provides AES-256-CBC message authentication then decryption. * * @arg {Buffer} secret - See PrivateKey.getSharedSecret() * @arg {Buffer} message - ciphertext (from checkEncrypt) * * @throws {Error} decrypt failed */ function checkDecrypt(secret, message) { var K = createHash("sha512").update(secret).digest(); var Ke = K.slice(0, 32); // Encryption var Km = K.slice(32); // MAC var IV = message.slice(0, 16); var C = message.slice(16, message.length - 32); var M = message.slice(message.length - 32); // Side-channel attack protection: First verify the HMAC, then and only then proceed to the decryption step var Mc = createHmac("sha256", Km).update(Buffer.concat([IV, C])).digest(); if (Buffer.compare(M, Mc) !== 0) { throw new Error("decrypt failed"); } // Cipher performs PKCS#5 padded automatically var cipher = crypto.createDecipheriv("aes-256-cbc", Ke, IV); return Buffer.concat([cipher.update(C, "binary"), cipher.final()]); } exports.checkDecrypt = checkDecrypt; //# sourceMappingURL=encryption-check.js.map