diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json
index 70c63b332..1afa6dcb5 100755
--- a/src/core/config/Categories.json
+++ b/src/core/config/Categories.json
@@ -105,11 +105,6 @@
"Derive EVP key",
"Bcrypt",
"Scrypt",
- "Generate RSA Key Pair",
- "RSA Sign",
- "RSA Verify",
- "RSA Encrypt",
- "RSA Decrypt",
"JWT Sign",
"JWT Verify",
"JWT Decode",
@@ -139,6 +134,11 @@
"PGP Verify",
"PGP Encrypt and Sign",
"PGP Decrypt and Verify",
+ "Generate RSA Key Pair",
+ "RSA Sign",
+ "RSA Verify",
+ "RSA Encrypt",
+ "RSA Decrypt",
"Parse SSH Host Key"
]
},
diff --git a/src/core/lib/RSA.mjs b/src/core/lib/RSA.mjs
index 0dab67a36..9037379cf 100644
--- a/src/core/lib/RSA.mjs
+++ b/src/core/lib/RSA.mjs
@@ -1,4 +1,12 @@
-import forge from "node-forge/dist/forge.min.js";
+/**
+ * RSA resources.
+ *
+ * @author Matt C [me@mitt.dev]
+ * @copyright Crown Copyright 2021
+ * @license Apache-2.0
+ */
+
+import forge from "node-forge";
export const MD_ALGORITHMS = {
"SHA-1": forge.md.sha1,
diff --git a/src/core/operations/GeneratePGPKeyPair.mjs b/src/core/operations/GeneratePGPKeyPair.mjs
index bb366b6ff..5943ce314 100644
--- a/src/core/operations/GeneratePGPKeyPair.mjs
+++ b/src/core/operations/GeneratePGPKeyPair.mjs
@@ -25,7 +25,7 @@ class GeneratePGPKeyPair extends Operation {
this.name = "Generate PGP Key Pair";
this.module = "PGP";
- this.description = "Generates a new public/private PGP key pair. Supports RSA and Eliptic Curve (EC) keys.";
+ this.description = "Generates a new public/private PGP key pair. Supports RSA and Eliptic Curve (EC) keys.
WARNING: Cryptographic operations in CyberChef should not be relied upon to provide security in any situation. No guarantee is offered for their correctness. We advise you not to use keys generated from CyberChef in operational contexts.";
this.infoURL = "https://wikipedia.org/wiki/Pretty_Good_Privacy";
this.inputType = "string";
this.outputType = "string";
diff --git a/src/core/operations/GenerateRSAKeyPair.mjs b/src/core/operations/GenerateRSAKeyPair.mjs
index 57cfcdd09..f263eb23c 100644
--- a/src/core/operations/GenerateRSAKeyPair.mjs
+++ b/src/core/operations/GenerateRSAKeyPair.mjs
@@ -5,8 +5,8 @@
* @license Apache-2.0
*/
-import Operation from "../Operation";
-import forge from "node-forge/dist/forge.min.js";
+import Operation from "../Operation.mjs";
+import forge from "node-forge";
/**
* Generate RSA Key Pair operation
@@ -21,7 +21,7 @@ class GenerateRSAKeyPair extends Operation {
this.name = "Generate RSA Key Pair";
this.module = "Ciphers";
- this.description = "Generate an RSA key pair with a given number of bits";
+ this.description = "Generate an RSA key pair with a given number of bits.
WARNING: Cryptographic operations in CyberChef should not be relied upon to provide security in any situation. No guarantee is offered for their correctness. We advise you not to use keys generated from CyberChef in operational contexts.";
this.infoURL = "https://wikipedia.org/wiki/RSA_(cryptosystem)";
this.inputType = "string";
this.outputType = "string";
@@ -56,7 +56,11 @@ class GenerateRSAKeyPair extends Operation {
const [keyLength, outputFormat] = args;
return new Promise((resolve, reject) => {
- forge.pki.rsa.generateKeyPair({ bits: Number(keyLength), workers: -1, workerScript: "assets/forge/prime.worker.min.js"}, (err, keypair) => {
+ forge.pki.rsa.generateKeyPair({
+ bits: Number(keyLength),
+ workers: -1,
+ workerScript: "assets/forge/prime.worker.min.js"
+ }, (err, keypair) => {
if (err) return reject(err);
let result;
diff --git a/src/core/operations/RSADecrypt.mjs b/src/core/operations/RSADecrypt.mjs
index eb24aeabc..5b32b7900 100644
--- a/src/core/operations/RSADecrypt.mjs
+++ b/src/core/operations/RSADecrypt.mjs
@@ -6,8 +6,7 @@
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
-import Utils from "../Utils.mjs";
-import forge from "node-forge/dist/forge.min.js";
+import forge from "node-forge";
import { MD_ALGORITHMS } from "../lib/RSA.mjs";
/**
@@ -25,7 +24,7 @@ class RSADecrypt extends Operation {
this.module = "Ciphers";
this.description = "Decrypt an RSA encrypted message with a PEM encoded private key.";
this.infoURL = "https://wikipedia.org/wiki/RSA_(cryptosystem)";
- this.inputType = "ArrayBuffer";
+ this.inputType = "string";
this.outputType = "string";
this.args = [
{
@@ -75,8 +74,8 @@ class RSADecrypt extends Operation {
}
try {
const privKey = forge.pki.decryptRsaPrivateKey(pemKey, password);
- const dMsg = privKey.decrypt(Utils.arrayBufferToStr(input), scheme, {md: MD_ALGORITHMS[md].create()});
- return dMsg;
+ const dMsg = privKey.decrypt(input, scheme, {md: MD_ALGORITHMS[md].create()});
+ return forge.util.decodeUtf8(dMsg);
} catch (err) {
throw new OperationError(err);
}
diff --git a/src/core/operations/RSAEncrypt.mjs b/src/core/operations/RSAEncrypt.mjs
index e788a668b..859ce132a 100644
--- a/src/core/operations/RSAEncrypt.mjs
+++ b/src/core/operations/RSAEncrypt.mjs
@@ -6,8 +6,7 @@
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
-import Utils from "../Utils.mjs";
-import forge from "node-forge/dist/forge.min.js";
+import forge from "node-forge";
import { MD_ALGORITHMS } from "../lib/RSA.mjs";
/**
@@ -26,7 +25,7 @@ class RSAEncrypt extends Operation {
this.description = "Encrypt a message with a PEM encoded RSA public key.";
this.infoURL = "https://wikipedia.org/wiki/RSA_(cryptosystem)";
this.inputType = "string";
- this.outputType = "ArrayBuffer";
+ this.outputType = "string";
this.args = [
{
name: "RSA Public Key (PEM)",
@@ -72,9 +71,11 @@ class RSAEncrypt extends Operation {
try {
// Load public key
const pubKey = forge.pki.publicKeyFromPem(pemKey);
+ // https://github.com/digitalbazaar/forge/issues/465#issuecomment-271097600
+ const plaintextBytes = forge.util.encodeUtf8(input);
// Encrypt message
- const eMsg = pubKey.encrypt(input, scheme, {md: MD_ALGORITHMS[md].create()});
- return Utils.strToArrayBuffer(eMsg);
+ const eMsg = pubKey.encrypt(plaintextBytes, scheme, {md: MD_ALGORITHMS[md].create()});
+ return eMsg;
} catch (err) {
if (err.message === "RSAES-OAEP input message length is too long.") {
throw new OperationError(`RSAES-OAEP input message length (${err.length}) is longer than the maximum allowed length (${err.maxLength}).`);
diff --git a/src/core/operations/RSASign.mjs b/src/core/operations/RSASign.mjs
index 6161c5fe5..25160f53c 100644
--- a/src/core/operations/RSASign.mjs
+++ b/src/core/operations/RSASign.mjs
@@ -5,9 +5,9 @@
* @license Apache-2.0
*/
-import Operation from "../Operation";
-import OperationError from "../errors/OperationError";
-import forge from "node-forge/dist/forge.min.js";
+import Operation from "../Operation.mjs";
+import OperationError from "../errors/OperationError.mjs";
+import forge from "node-forge";
import { MD_ALGORITHMS } from "../lib/RSA.mjs";
/**
diff --git a/src/core/operations/RSAVerify.mjs b/src/core/operations/RSAVerify.mjs
index e1a8b0cb1..89b7d81f0 100644
--- a/src/core/operations/RSAVerify.mjs
+++ b/src/core/operations/RSAVerify.mjs
@@ -6,7 +6,7 @@
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
-import forge from "node-forge/dist/forge.min.js";
+import forge from "node-forge";
import { MD_ALGORITHMS } from "../lib/RSA.mjs";
/**
diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs
index 50079b827..d20ccc61a 100644
--- a/tests/operations/index.mjs
+++ b/tests/operations/index.mjs
@@ -101,12 +101,11 @@ import "./tests/CipherSaber2.mjs";
import "./tests/Colossus.mjs";
import "./tests/ParseObjectIDTimestamp.mjs";
import "./tests/Unicode.mjs";
-
+import "./tests/RSA.mjs";
// Cannot test operations that use the File type yet
// import "./tests/SplitColourChannels.mjs";
-// Cannot test as minified forge does not support node
-// import "./tests/RSA.mjs";
+
const testStatus = {
allTestsPassing: true,
counts: {
diff --git a/tests/operations/samples/Ciphers.mjs b/tests/operations/samples/Ciphers.mjs
index a1363d834..2d9751313 100644
--- a/tests/operations/samples/Ciphers.mjs
+++ b/tests/operations/samples/Ciphers.mjs
@@ -1,3 +1,12 @@
+/**
+ * Various types of input data for use in tests
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @author Matt C [me@mitt.dev]
+ * @copyright Crown Copyright 2020
+ * @license Apache-2.0
+ */
+
export const ASCII_TEXT = "A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools.";
export const UTF8_TEXT = "Шанцы на высвятленне таго, што адбываецца на самай справе ў сусвеце настолькі выдаленыя, адзінае, што трэба зрабіць, гэта павесіць пачуццё яго і трымаць сябе занятымі.";
diff --git a/tests/operations/tests/RSA.mjs b/tests/operations/tests/RSA.mjs
index 2ade56478..33e7139f4 100644
--- a/tests/operations/tests/RSA.mjs
+++ b/tests/operations/tests/RSA.mjs
@@ -79,8 +79,8 @@ TestRegister.addTests([
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-1, UTF-8",
- input: UTF8_TEXT,
- expectedOutput: UTF8_TEXT,
+ input: UTF8_TEXT.substr(0, 100),
+ expectedOutput: UTF8_TEXT.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
@@ -94,8 +94,8 @@ TestRegister.addTests([
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-1, All bytes",
- input: ALL_BYTES,
- expectedOutput: ALL_BYTES,
+ input: ALL_BYTES.substr(0, 100),
+ expectedOutput: ALL_BYTES.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
@@ -139,8 +139,8 @@ TestRegister.addTests([
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/MD5, UTF-8",
- input: UTF8_TEXT,
- expectedOutput: UTF8_TEXT,
+ input: UTF8_TEXT.substr(0, 100),
+ expectedOutput: UTF8_TEXT.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
@@ -154,8 +154,8 @@ TestRegister.addTests([
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/MD5, All bytes",
- input: ALL_BYTES,
- expectedOutput: ALL_BYTES,
+ input: ALL_BYTES.substr(0, 100),
+ expectedOutput: ALL_BYTES.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
@@ -199,8 +199,8 @@ TestRegister.addTests([
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-256, UTF-8",
- input: UTF8_TEXT,
- expectedOutput: UTF8_TEXT,
+ input: UTF8_TEXT.substr(0, 100),
+ expectedOutput: UTF8_TEXT.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
@@ -214,8 +214,8 @@ TestRegister.addTests([
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-256, All bytes",
- input: ALL_BYTES,
- expectedOutput: ALL_BYTES,
+ input: ALL_BYTES.substr(0, 100),
+ expectedOutput: ALL_BYTES.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
@@ -259,8 +259,8 @@ TestRegister.addTests([
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-384, UTF-8",
- input: UTF8_TEXT,
- expectedOutput: UTF8_TEXT,
+ input: UTF8_TEXT.substr(0, 80),
+ expectedOutput: UTF8_TEXT.substr(0, 80),
recipeConfig: [
{
"op": "RSA Encrypt",
@@ -274,8 +274,8 @@ TestRegister.addTests([
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-384, All bytes",
- input: ALL_BYTES,
- expectedOutput: ALL_BYTES,
+ input: ALL_BYTES.substr(0, 100),
+ expectedOutput: ALL_BYTES.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
@@ -304,8 +304,8 @@ TestRegister.addTests([
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-512, ASCII",
- input: ASCII_TEXT,
- expectedOutput: ASCII_TEXT,
+ input: ASCII_TEXT.substr(0, 100),
+ expectedOutput: ASCII_TEXT.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",
@@ -319,8 +319,8 @@ TestRegister.addTests([
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-512, UTF-8",
- input: UTF8_TEXT,
- expectedOutput: UTF8_TEXT,
+ input: UTF8_TEXT.substr(0, 60),
+ expectedOutput: UTF8_TEXT.substr(0, 60),
recipeConfig: [
{
"op": "RSA Encrypt",
@@ -334,8 +334,8 @@ TestRegister.addTests([
},
{
name: "RSA Encrypt/Decrypt: RSA-OAEP/SHA-512, All bytes",
- input: ALL_BYTES,
- expectedOutput: ALL_BYTES,
+ input: ALL_BYTES.substr(0, 100),
+ expectedOutput: ALL_BYTES.substr(0, 100),
recipeConfig: [
{
"op": "RSA Encrypt",