UNPKG

@meeco/cryppo

Version:

In-browser encryption and decryption. Clone of Ruby Cryppo

95 lines 4.05 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DerivedKeyOptions = exports.KeyDerivationStrategy = void 0; const node_forge_1 = __importDefault(require("node-forge")); const encoding_versions_js_1 = require("../encoding-versions.js"); const encryption_key_js_1 = require("../encryption-key.js"); const serialization_versions_js_1 = require("../serialization-versions.js"); const util_js_1 = require("../util.js"); const { md, pkcs5, random } = node_forge_1.default; /** * Most of these values are copied directly from the Ruby library */ const MIN_ITERATIONS = 20000; const DEFAULT_LENGTH = 32; const DEFAULT_ITERATION_VARIANCE = 10; const DEFAULT_SALT_LENGTH = 20; var KeyDerivationStrategy; (function (KeyDerivationStrategy) { KeyDerivationStrategy["Pbkdf2Hmac"] = "Pbkdf2Hmac"; })(KeyDerivationStrategy || (exports.KeyDerivationStrategy = KeyDerivationStrategy = {})); /** * Store configuration used for password based key derivation and * serialize/de-serialize it. */ class DerivedKeyOptions { static usesDerivedKey(serialized) { const parts = serialized.split('.'); if (parts[parts.length - 2] === KeyDerivationStrategy.Pbkdf2Hmac) { return true; } return false; } static randomFromOptions({ iterationVariance = DEFAULT_ITERATION_VARIANCE, length = DEFAULT_LENGTH, minIterations = MIN_ITERATIONS, strategy = KeyDerivationStrategy.Pbkdf2Hmac, useSalt, }) { const variance = Math.floor(minIterations * (iterationVariance / 100)); const iterations = minIterations + Math.floor(Math.random() * variance); const salt = useSalt || random.getBytesSync(DEFAULT_SALT_LENGTH); return new DerivedKeyOptions({ strategy, iterations, salt, length, }); } static fromSerialized(serialized) { const { derivationStrategy, serializationArtifacts } = (0, util_js_1.deSerializeDerivedKeyOptions)(serialized); return new DerivedKeyOptions({ // keys taken from ruby lib strategy: derivationStrategy, salt: (0, util_js_1.bytesBufferToBinaryString)(serializationArtifacts.iv), iterations: serializationArtifacts.i, length: serializationArtifacts.l, hash: serializationArtifacts.hash, ...serializationArtifacts, }); } salt; iterations; length; strategy; hash; constructor(options) { this.salt = options.salt; this.iterations = options.iterations; this.length = options.length; this.strategy = options.strategy; this.hash = options.hash || 'SHA256'; } serialize(serializationVersion = serialization_versions_js_1.SerializationFormat.latest_version) { // keys taken from ruby lib return (0, util_js_1.serializeDerivedKeyOptions)(this.strategy, { iv: (0, util_js_1.binaryStringToBytesBuffer)(this.salt), i: this.iterations, l: this.length, hash: this.hash, }, serializationVersion); } deriveKey(key, encodingVersion = encoding_versions_js_1.EncodingVersions.latest_version) { const hash = this.hash.toLocaleLowerCase(); const digest = md[hash].create(); key = encodingVersion === encoding_versions_js_1.EncodingVersions.legacy ? key : (0, util_js_1.encodeUtf8)(key); return new Promise((resolve, reject) => { return pkcs5.pbkdf2(key, this.salt, this.iterations, this.length, digest, (err, derivedKey) => { if (err) { return reject(err); } resolve(encryption_key_js_1.EncryptionKey.fromBytes((0, util_js_1.binaryStringToBytes)(derivedKey))); }); }); } } exports.DerivedKeyOptions = DerivedKeyOptions; //# sourceMappingURL=derived-key.js.map