diff --git a/src/core/operations/DESDecrypt.mjs b/src/core/operations/DESDecrypt.mjs
index 4c8a37ce..9cdcf5fd 100644
--- a/src/core/operations/DESDecrypt.mjs
+++ b/src/core/operations/DESDecrypt.mjs
@@ -69,6 +69,7 @@ class DESDecrypt extends Operation {
if (key.length !== 8) {
return `Invalid key length: ${key.length} bytes
+
DES uses a key length of 8 bytes (64 bits).
Triple DES uses a key length of 24 bytes (192 bits).`;
}
diff --git a/src/core/operations/DerivePBKDF2Key.mjs b/src/core/operations/DerivePBKDF2Key.mjs
new file mode 100644
index 00000000..d3f7fe9a
--- /dev/null
+++ b/src/core/operations/DerivePBKDF2Key.mjs
@@ -0,0 +1,77 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import forge from "node-forge/dist/forge.min.js";
+
+/**
+ * Derive PBKDF2 key operation
+ */
+class DerivePBKDF2Key extends Operation {
+
+ /**
+ * DerivePBKDF2Key constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Derive PBKDF2 key";
+ this.module = "Ciphers";
+ this.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.";
+ this.inputType = "string";
+ this.outputType = "string";
+ this.args = [
+ {
+ "name": "Passphrase",
+ "type": "toggleString",
+ "value": "",
+ "toggleValues": ["UTF8", "Latin1", "Hex", "Base64"]
+ },
+ {
+ "name": "Key size",
+ "type": "number",
+ "value": 128
+ },
+ {
+ "name": "Iterations",
+ "type": "number",
+ "value": 1
+ },
+ {
+ "name": "Hashing function",
+ "type": "option",
+ "value": ["SHA1", "SHA256", "SHA384", "SHA512", "MD5"]
+ },
+ {
+ "name": "Salt",
+ "type": "toggleString",
+ "value": "",
+ "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
+ }
+ ];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ const passphrase = Utils.convertToByteString(args[0].string, args[0].option),
+ keySize = args[1],
+ iterations = args[2],
+ hasher = args[3],
+ salt = Utils.convertToByteString(args[4].string, args[4].option) ||
+ forge.random.getBytesSync(keySize),
+ derivedKey = forge.pkcs5.pbkdf2(passphrase, salt, iterations, keySize / 8, hasher.toLowerCase());
+
+ return forge.util.bytesToHex(derivedKey);
+ }
+
+}
+
+export default DerivePBKDF2Key;
diff --git a/src/core/operations/RC2Decrypt.mjs b/src/core/operations/RC2Decrypt.mjs
new file mode 100644
index 00000000..77dc5da5
--- /dev/null
+++ b/src/core/operations/RC2Decrypt.mjs
@@ -0,0 +1,76 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import forge from "node-forge/dist/forge.min.js";
+
+/**
+ * RC2 Decrypt operation
+ */
+class RC2Decrypt extends Operation {
+
+ /**
+ * RC2Decrypt constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "RC2 Decrypt";
+ this.module = "Ciphers";
+ this.description = "RC2 (also known as ARC2) is a symmetric-key block cipher designed by Ron Rivest in 1987. 'RC' stands for 'Rivest Cipher'.
Key: RC2 uses a variable size key.
IV: To run the cipher in CBC mode, the Initialization Vector should be 8 bytes long. If the IV is left blank, the cipher will run in ECB mode.
Padding: In both CBC and ECB mode, PKCS#7 padding will be used.";
+ this.inputType = "string";
+ this.outputType = "string";
+ this.args = [
+ {
+ "name": "Key",
+ "type": "toggleString",
+ "value": "",
+ "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
+ },
+ {
+ "name": "IV",
+ "type": "toggleString",
+ "value": "",
+ "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
+ },
+ {
+ "name": "Input",
+ "type": "option",
+ "value": ["Hex", "Raw"]
+ },
+ {
+ "name": "Output",
+ "type": "option",
+ "value": ["Raw", "Hex"]
+ }
+ ];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ const key = Utils.convertToByteString(args[0].string, args[0].option),
+ iv = Utils.convertToByteString(args[1].string, args[1].option),
+ inputType = args[2],
+ outputType = args[3],
+ decipher = forge.rc2.createDecryptionCipher(key);
+
+ input = Utils.convertToByteString(input, inputType);
+
+ decipher.start(iv || null);
+ decipher.update(forge.util.createBuffer(input));
+ decipher.finish();
+
+ return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes();
+ }
+
+}
+
+export default RC2Decrypt;
diff --git a/src/core/operations/RC2Encrypt.mjs b/src/core/operations/RC2Encrypt.mjs
new file mode 100644
index 00000000..0c2fcd61
--- /dev/null
+++ b/src/core/operations/RC2Encrypt.mjs
@@ -0,0 +1,77 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import forge from "node-forge/dist/forge.min.js";
+
+
+/**
+ * RC2 Encrypt operation
+ */
+class RC2Encrypt extends Operation {
+
+ /**
+ * RC2Encrypt constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "RC2 Encrypt";
+ this.module = "Ciphers";
+ this.description = "RC2 (also known as ARC2) is a symmetric-key block cipher designed by Ron Rivest in 1987. 'RC' stands for 'Rivest Cipher'.
Key: RC2 uses a variable size key.
You can generate a password-based key using one of the KDF operations.
IV: To run the cipher in CBC mode, the Initialization Vector should be 8 bytes long. If the IV is left blank, the cipher will run in ECB mode.
Padding: In both CBC and ECB mode, PKCS#7 padding will be used.";
+ this.inputType = "string";
+ this.outputType = "string";
+ this.args = [
+ {
+ "name": "Key",
+ "type": "toggleString",
+ "value": "",
+ "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
+ },
+ {
+ "name": "IV",
+ "type": "toggleString",
+ "value": "",
+ "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
+ },
+ {
+ "name": "Input",
+ "type": "option",
+ "value": ["Raw", "Hex"]
+ },
+ {
+ "name": "Output",
+ "type": "option",
+ "value": ["Hex", "Raw"]
+ }
+ ];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ const key = Utils.convertToByteString(args[0].string, args[0].option),
+ iv = Utils.convertToByteString(args[1].string, args[1].option),
+ inputType = args[2],
+ outputType = args[3],
+ cipher = forge.rc2.createEncryptionCipher(key);
+
+ input = Utils.convertToByteString(input, inputType);
+
+ cipher.start(iv || null);
+ cipher.update(forge.util.createBuffer(input));
+ cipher.finish();
+
+ return outputType === "Hex" ? cipher.output.toHex() : cipher.output.getBytes();
+ }
+
+}
+
+export default RC2Encrypt;
diff --git a/src/core/operations/legacy/Cipher.js b/src/core/operations/legacy/Cipher.js
deleted file mode 100755
index 3a81281d..00000000
--- a/src/core/operations/legacy/Cipher.js
+++ /dev/null
@@ -1,175 +0,0 @@
-import Utils from "../Utils.js";
-import forge from "imports-loader?jQuery=>null!node-forge/dist/forge.min.js";
-import BigNumber from "bignumber.js";
-
-
-/**
- * Cipher operations.
- *
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- *
- * @namespace
- */
-const Cipher = {
-
- /**
- * @constant
- * @default
- */
- IO_FORMAT1: ["Hex", "UTF8", "Latin1", "Base64"],
- /**
- * @constant
- * @default
- */
- IO_FORMAT2: ["UTF8", "Latin1", "Hex", "Base64"],
- /**
- * @constant
- * @default
- */
- IO_FORMAT3: ["Raw", "Hex"],
- /**
- * @constant
- * @default
- */
- IO_FORMAT4: ["Hex", "Raw"],
-
-
- /**
- * RC2 Encrypt operation.
- *
- * @param {string} input
- * @param {Object[]} args
- * @returns {string}
- */
- runRc2Enc: function (input, args) {
- const key = Utils.convertToByteString(args[0].string, args[0].option),
- iv = Utils.convertToByteString(args[1].string, args[1].option),
- inputType = args[2],
- outputType = args[3],
- cipher = forge.rc2.createEncryptionCipher(key);
-
- input = Utils.convertToByteString(input, inputType);
-
- cipher.start(iv || null);
- cipher.update(forge.util.createBuffer(input));
- cipher.finish();
-
- return outputType === "Hex" ? cipher.output.toHex() : cipher.output.getBytes();
- },
-
-
- /**
- * RC2 Decrypt operation.
- *
- * @param {string} input
- * @param {Object[]} args
- * @returns {string}
- */
- runRc2Dec: function (input, args) {
- const key = Utils.convertToByteString(args[0].string, args[0].option),
- iv = Utils.convertToByteString(args[1].string, args[1].option),
- inputType = args[2],
- outputType = args[3],
- decipher = forge.rc2.createDecryptionCipher(key);
-
- input = Utils.convertToByteString(input, inputType);
-
- decipher.start(iv || null);
- decipher.update(forge.util.createBuffer(input));
- decipher.finish();
-
- return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes();
- },
-
-
- /**
- * @constant
- * @default
- */
- KDF_KEY_SIZE: 128,
- /**
- * @constant
- * @default
- */
- KDF_ITERATIONS: 1,
- /**
- * @constant
- * @default
- */
- HASHERS: ["SHA1", "SHA256", "SHA384", "SHA512", "MD5"],
-
- /**
- * Derive PBKDF2 key operation.
- *
- * @param {string} input
- * @param {Object[]} args
- * @returns {string}
- */
- runPbkdf2: function (input, args) {
- const passphrase = Utils.convertToByteString(args[0].string, args[0].option),
- keySize = args[1],
- iterations = args[2],
- hasher = args[3],
- salt = Utils.convertToByteString(args[4].string, args[4].option) ||
- forge.random.getBytesSync(keySize),
- derivedKey = forge.pkcs5.pbkdf2(passphrase, salt, iterations, keySize / 8, hasher.toLowerCase());
-
- return forge.util.bytesToHex(derivedKey);
- },
-
-
- /**
- * @constant
- * @default
- */
- PRNG_BYTES: 32,
- /**
- * @constant
- * @default
- */
- PRNG_OUTPUT: ["Hex", "Integer", "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 = new BigNumber(0),
- i;
-
- switch (outputAs) {
- case "Hex":
- return forge.util.bytesToHex(bytes);
- case "Integer":
- for (i = bytes.length - 1; i >= 0; i--) {
- value = value.times(256).plus(bytes.charCodeAt(i));
- }
- return value.toFixed();
- case "Byte array":
- return JSON.stringify(Utils.strToCharcode(bytes));
- case "Raw":
- default:
- return bytes;
- }
- },
-
-};
-
-export default Cipher;
diff --git a/test/index.mjs b/test/index.mjs
index a20d5fa6..07312fa4 100644
--- a/test/index.mjs
+++ b/test/index.mjs
@@ -36,7 +36,7 @@ import "./tests/operations/Ciphers";
import "./tests/operations/Checksum";
// import "./tests/operations/Code";
import "./tests/operations/Compress";
-// import "./tests/operations/Crypt";
+import "./tests/operations/Crypt";
import "./tests/operations/DateTime";
import "./tests/operations/Fork";
import "./tests/operations/Jump";