diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js index 293e393..2038ad5 100755 --- a/src/core/config/Categories.js +++ b/src/core/config/Categories.js @@ -99,6 +99,7 @@ const Categories = [ "Substitute", "Derive PBKDF2 key", "Derive EVP key", + "Pseudo-Random Number Generator", ] }, { @@ -198,6 +199,7 @@ const Categories = [ "Parse colour code", "Escape string", "Unescape string", + "Pseudo-Random Number Generator", ] }, { @@ -313,6 +315,7 @@ const Categories = [ "Detect File Type", "Scan for Embedded Files", "Disassemble x86", + "Pseudo-Random Number Generator", "Generate UUID", "Generate TOTP", "Generate HOTP", diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 0b2a99f..a020c99 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -1503,6 +1503,24 @@ const OperationConfig = { }, ] }, + "Pseudo-Random Number Generator": { + module: "Ciphers", + description: "A cryptographically-secure pseudo-random number generator (PRNG).

This operation uses the browser's built-in crypto.getRandomValues() method if available. If this cannot be found, it falls back to a Fortuna-based PRNG algorithm.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Number of bytes", + type: "number", + value: Cipher.PRNG_BYTES + }, + { + name: "Output as", + type: "option", + value: Cipher.PRNG_OUTPUT + } + ] + }, "Derive PBKDF2 key": { module: "Ciphers", description: "PBKDF2 is a password-based key derivation function. It is part of RSA Laboratories' Public-Key Cryptography Standards (PKCS) series, specifically PKCS #5 v2.0, also published as Internet Engineering Task Force's RFC 2898.

In many applications of cryptography, user security is ultimately dependent on a password, and because a password usually can't be used directly as a cryptographic key, some processing is required.

A salt provides a large set of keys for any given password, and an iteration count increases the cost of producing keys from a password, thereby also increasing the difficulty of attack.

If you leave the salt argument empty, a random salt will be generated.", diff --git a/src/core/config/modules/Ciphers.js b/src/core/config/modules/Ciphers.js index d5ebe2f..3f8ae51 100644 --- a/src/core/config/modules/Ciphers.js +++ b/src/core/config/modules/Ciphers.js @@ -38,6 +38,7 @@ OpModules.Ciphers = { "Affine Cipher Decode": Cipher.runAffineDec, "Atbash Cipher": Cipher.runAtbash, "Substitute": Cipher.runSubstitute, + "Pseudo-Random Number Generator": Cipher.runPRNG, }; export default OpModules; diff --git a/src/core/operations/Cipher.js b/src/core/operations/Cipher.js index ca63c48..8799f05 100755 --- a/src/core/operations/Cipher.js +++ b/src/core/operations/Cipher.js @@ -437,7 +437,7 @@ DES uses a key length of 8 bytes (64 bits).`; forge.random.getBytesSync(keySize), derivedKey = forge.pkcs5.pbkdf2(passphrase, salt, iterations, keySize / 8, hasher.toLowerCase()); - return Utils.toHexFast(Utils.strToCharcode(derivedKey)); + return forge.util.bytesToHex(derivedKey); }, @@ -515,6 +515,53 @@ DES uses a key length of 8 bytes (64 bits).`; }, + /** + * @constant + * @default + */ + PRNG_BYTES: 32, + PRNG_OUTPUT: ["Hex", "Number", "Byte array", "Raw"], + + /** + * Pseudo-Random Number Generator operation. + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + runPRNG: function(input, args) { + const numBytes = args[0], + outputAs = args[1]; + + let bytes; + + if (ENVIRONMENT_IS_WORKER() && self.crypto) { + bytes = self.crypto.getRandomValues(new Uint8Array(numBytes)); + bytes = Utils.arrayBufferToStr(bytes.buffer); + } else { + bytes = forge.random.getBytesSync(numBytes); + } + + let value = 0, + i; + + switch (outputAs) { + case "Hex": + return forge.util.bytesToHex(bytes); + case "Number": + for (i = bytes.length - 1; i >= 0; i--) { + value = (value * 256) + bytes.charCodeAt(i); + } + return value.toString(); + case "Byte array": + return JSON.stringify(Utils.strToCharcode(bytes)); + case "Raw": + default: + return bytes; + } + }, + + /** * Vigenère Encode operation. *