diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json
index 70c63b33..1afa6dcb 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 0dab67a3..9037379c 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 bb366b6f..5943ce31 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 57cfcdd0..f263eb23 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 eb24aeab..5b32b790 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 e788a668..859ce132 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 6161c5fe..25160f53 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 e1a8b0cb..89b7d81f 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 50079b82..d20ccc61 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 a1363d83..2d975131 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 2ade5647..33e7139f 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",