mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-20 23:06:16 -04:00
Converted PBKDF2 and RC2, enabled tests, deleted legacy Cipher file
Also made DESDecrypt test pass
This commit is contained in:
parent
46b8b2fa7e
commit
9ffab374db
6 changed files with 232 additions and 176 deletions
|
@ -69,6 +69,7 @@ class DESDecrypt extends Operation {
|
||||||
|
|
||||||
if (key.length !== 8) {
|
if (key.length !== 8) {
|
||||||
return `Invalid key length: ${key.length} bytes
|
return `Invalid key length: ${key.length} bytes
|
||||||
|
|
||||||
DES uses a key length of 8 bytes (64 bits).
|
DES uses a key length of 8 bytes (64 bits).
|
||||||
Triple DES uses a key length of 24 bytes (192 bits).`;
|
Triple DES uses a key length of 24 bytes (192 bits).`;
|
||||||
}
|
}
|
||||||
|
|
77
src/core/operations/DerivePBKDF2Key.mjs
Normal file
77
src/core/operations/DerivePBKDF2Key.mjs
Normal file
|
@ -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.<br><br>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.<br><br>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.<br><br>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;
|
76
src/core/operations/RC2Decrypt.mjs
Normal file
76
src/core/operations/RC2Decrypt.mjs
Normal file
|
@ -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'.<br><br><b>Key:</b> RC2 uses a variable size key.<br><br><b>IV:</b> 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.<br><br><b>Padding:</b> 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;
|
77
src/core/operations/RC2Encrypt.mjs
Normal file
77
src/core/operations/RC2Encrypt.mjs
Normal file
|
@ -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'.<br><br><b>Key:</b> RC2 uses a variable size key.<br><br>You can generate a password-based key using one of the KDF operations.<br><br><b>IV:</b> 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.<br><br><b>Padding:</b> 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;
|
|
@ -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;
|
|
|
@ -36,7 +36,7 @@ import "./tests/operations/Ciphers";
|
||||||
import "./tests/operations/Checksum";
|
import "./tests/operations/Checksum";
|
||||||
// import "./tests/operations/Code";
|
// import "./tests/operations/Code";
|
||||||
import "./tests/operations/Compress";
|
import "./tests/operations/Compress";
|
||||||
// import "./tests/operations/Crypt";
|
import "./tests/operations/Crypt";
|
||||||
import "./tests/operations/DateTime";
|
import "./tests/operations/DateTime";
|
||||||
import "./tests/operations/Fork";
|
import "./tests/operations/Fork";
|
||||||
import "./tests/operations/Jump";
|
import "./tests/operations/Jump";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue