diff --git a/src/core/operations/AESDecrypt.mjs b/src/core/operations/AESDecrypt.mjs
new file mode 100644
index 00000000..01415ddc
--- /dev/null
+++ b/src/core/operations/AESDecrypt.mjs
@@ -0,0 +1,105 @@
+/**
+ * @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";
+
+/**
+ * AES Decrypt operation
+ */
+class AESDecrypt extends Operation {
+
+ /**
+ * AESDecrypt constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "AES Decrypt";
+ this.module = "Ciphers";
+ this.description = "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.
Key: The following algorithms will be used based on the size of the key:
- 16 bytes = AES-128
- 24 bytes = AES-192
- 32 bytes = AES-256
IV: The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.
Padding: In CBC and ECB mode, PKCS#7 padding will be used.
GCM Tag: This field is ignored unless 'GCM' mode is 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": "Mode",
+ "type": "option",
+ "value": ["CBC", "CFB", "OFB", "CTR", "GCM", "ECB"]
+ },
+ {
+ "name": "Input",
+ "type": "option",
+ "value": ["Hex", "Raw"]
+ },
+ {
+ "name": "Output",
+ "type": "option",
+ "value": ["Raw", "Hex"]
+ },
+ {
+ "name": "GCM Tag",
+ "type": "toggleString",
+ "value": "",
+ "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
+ }
+ ];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ const key = Utils.convertToByteArray(args[0].string, args[0].option),
+ iv = Utils.convertToByteArray(args[1].string, args[1].option),
+ mode = args[2],
+ inputType = args[3],
+ outputType = args[4],
+ gcmTag = Utils.convertToByteString(args[5].string, args[5].option);
+
+ if ([16, 24, 32].indexOf(key.length) < 0) {
+ return `Invalid key length: ${key.length} bytes
+
+The following algorithms will be used based on the size of the key:
+ 16 bytes = AES-128
+ 24 bytes = AES-192
+ 32 bytes = AES-256`;
+ }
+
+ input = Utils.convertToByteString(input, inputType);
+
+ const decipher = forge.cipher.createDecipher("AES-" + mode, key);
+ decipher.start({
+ iv: iv,
+ tag: gcmTag
+ });
+ decipher.update(forge.util.createBuffer(input));
+ const result = decipher.finish();
+
+ if (result) {
+ return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes();
+ } else {
+ return "Unable to decrypt input with these parameters.";
+ }
+ }
+
+}
+
+export default AESDecrypt;
diff --git a/src/core/operations/AESEncrypt.mjs b/src/core/operations/AESEncrypt.mjs
new file mode 100644
index 00000000..62763c5f
--- /dev/null
+++ b/src/core/operations/AESEncrypt.mjs
@@ -0,0 +1,103 @@
+/**
+ * @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";
+
+/**
+ * AES Encrypt operation
+ */
+class AESEncrypt extends Operation {
+
+ /**
+ * AESEncrypt constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "AES Encrypt";
+ this.module = "Ciphers";
+ this.description = "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.
Key: The following algorithms will be used based on the size of the key:- 16 bytes = AES-128
- 24 bytes = AES-192
- 32 bytes = AES-256
You can generate a password-based key using one of the KDF operations.
IV: The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.
Padding: In 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": "Mode",
+ "type": "option",
+ "value": ["CBC", "CFB", "OFB", "CTR", "GCM", "ECB"]
+ },
+ {
+ "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.convertToByteArray(args[0].string, args[0].option),
+ iv = Utils.convertToByteArray(args[1].string, args[1].option),
+ mode = args[2],
+ inputType = args[3],
+ outputType = args[4];
+
+ if ([16, 24, 32].indexOf(key.length) < 0) {
+ return `Invalid key length: ${key.length} bytes
+
+The following algorithms will be used based on the size of the key:
+ 16 bytes = AES-128
+ 24 bytes = AES-192
+ 32 bytes = AES-256`;
+ }
+
+ input = Utils.convertToByteString(input, inputType);
+
+ const cipher = forge.cipher.createCipher("AES-" + mode, key);
+ cipher.start({iv: iv});
+ cipher.update(forge.util.createBuffer(input));
+ cipher.finish();
+
+ if (outputType === "Hex") {
+ if (mode === "GCM") {
+ return cipher.output.toHex() + "\n\n" +
+ "Tag: " + cipher.mode.tag.toHex();
+ }
+ return cipher.output.toHex();
+ } else {
+ if (mode === "GCM") {
+ return cipher.output.getBytes() + "\n\n" +
+ "Tag: " + cipher.mode.tag.getBytes();
+ }
+ return cipher.output.getBytes();
+ }
+ }
+
+}
+
+export default AESEncrypt;
diff --git a/webpack.config.js b/webpack.config.js
index 3f88cc78..822c8561 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -69,6 +69,10 @@ module.exports = {
exclude: /node_modules\/(?!jsesc)/,
loader: "babel-loader?compact=false"
},
+ {
+ test: /forge.min.js$/,
+ loader: "imports-loader?jQuery=>null"
+ },
{
test: /\.css$/,
use: ExtractTextPlugin.extract({