mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-24 00:36:16 -04:00
Merge branch 'master' into base92
This commit is contained in:
commit
b118932451
36 changed files with 1332 additions and 105 deletions
|
@ -35,6 +35,17 @@ class AnalyseHash extends Operation {
|
|||
run(input, args) {
|
||||
input = input.replace(/\s/g, "");
|
||||
|
||||
// analyze hash if it is bcrypt
|
||||
if (/^\$2[abxy]?\$[0-9]+\$[a-zA-Z0-9/.]{53}$/.test(input)) {
|
||||
input = input.split("$");
|
||||
return "Hash algorithm Identifier: $" + input[1] + "$\n" +
|
||||
"Rounds: " + input[2] + "\n" +
|
||||
"Base64 encoded Input salt(22 bytes): " + input[3].slice(0, 22) + "\n" +
|
||||
"Base64 encoded hash(31 bytes): " + input[3].slice(22) + "\n\n" +
|
||||
"Based on the length, this hash could have been generated by one of the following hashing functions:\n" +
|
||||
"bcrypt";
|
||||
}
|
||||
|
||||
let output = "",
|
||||
possibleHashFunctions = [];
|
||||
const byteLength = input.length / 2,
|
||||
|
|
|
@ -21,7 +21,7 @@ class CTPH extends Operation {
|
|||
this.name = "CTPH";
|
||||
this.module = "Crypto";
|
||||
this.description = "Context Triggered Piecewise Hashing, also called Fuzzy Hashing, can match inputs that have homologies. Such inputs have sequences of identical bytes in the same order, although bytes in between these sequences may be different in both content and length.<br><br>CTPH was originally based on the work of Dr. Andrew Tridgell and a spam email detector called SpamSum. This method was adapted by Jesse Kornblum and published at the DFRWS conference in 2006 in a paper 'Identifying Almost Identical Files Using Context Triggered Piecewise Hashing'.";
|
||||
this.infoURL = "https://forensicswiki.xyz/wiki/index.php?title=Context_Triggered_Piecewise_Hashing";
|
||||
this.infoURL = "https://forensics.wiki/context_triggered_piecewise_hashing/";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
|
|
|
@ -24,7 +24,7 @@ class CompareCTPHHashes extends Operation {
|
|||
this.name = "Compare CTPH hashes";
|
||||
this.module = "Crypto";
|
||||
this.description = "Compares two Context Triggered Piecewise Hashing (CTPH) fuzzy hashes to determine the similarity between them on a scale of 0 to 100.";
|
||||
this.infoURL = "https://forensicswiki.xyz/wiki/index.php?title=Context_Triggered_Piecewise_Hashing";
|
||||
this.infoURL = "https://forensics.wiki/context_triggered_piecewise_hashing/";
|
||||
this.inputType = "string";
|
||||
this.outputType = "Number";
|
||||
this.args = [
|
||||
|
|
|
@ -24,7 +24,7 @@ class CompareSSDEEPHashes extends Operation {
|
|||
this.name = "Compare SSDEEP hashes";
|
||||
this.module = "Crypto";
|
||||
this.description = "Compares two SSDEEP fuzzy hashes to determine the similarity between them on a scale of 0 to 100.";
|
||||
this.infoURL = "https://forensicswiki.xyz/wiki/index.php?title=Ssdeep";
|
||||
this.infoURL = "https://forensics.wiki/ssdeep/";
|
||||
this.inputType = "string";
|
||||
this.outputType = "Number";
|
||||
this.args = [
|
||||
|
|
|
@ -39,7 +39,7 @@ class ExtractFiles extends Operation {
|
|||
${supportedExts.join("</li><li>")}
|
||||
</li>
|
||||
</ul>Minimum File Size can be used to prune small false positives.`;
|
||||
this.infoURL = "https://forensicswiki.xyz/wiki/index.php?title=File_Carving";
|
||||
this.infoURL = "https://forensics.wiki/file_carving";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "List<File>";
|
||||
this.presentType = "html";
|
||||
|
|
|
@ -66,7 +66,7 @@ class ExtractIPAddresses extends Operation {
|
|||
run(input, args) {
|
||||
const [includeIpv4, includeIpv6, removeLocal, displayTotal, sort, unique] = args,
|
||||
ipv4 = "(?:(?:\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d|\\d)(?:\\/\\d{1,2})?",
|
||||
ipv6 = "((?=.*::)(?!.*::.+::)(::)?([\\dA-F]{1,4}:(:|\\b)|){5}|([\\dA-F]{1,4}:){6})((([\\dA-F]{1,4}((?!\\3)::|:\\b|(?![\\dA-F])))|(?!\\2\\3)){2}|(((2[0-4]|1\\d|[1-9])?\\d|25[0-5])\\.?\\b){4})";
|
||||
ipv6 = "((?=.*::)(?!.*::.+::)(::)?([\\dA-F]{1,4}:(:|\\b)|){5}|([\\dA-F]{1,4}:){6})(([\\dA-F]{1,4}((?!\\3)::|:\\b|(?![\\dA-F])))|(?!\\2\\3)){2}";
|
||||
let ips = "";
|
||||
|
||||
if (includeIpv4 && includeIpv6) {
|
||||
|
|
138
src/core/operations/GOSTDecrypt.mjs
Normal file
138
src/core/operations/GOSTDecrypt.mjs
Normal file
|
@ -0,0 +1,138 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import { toHexFast, fromHex } from "../lib/Hex.mjs";
|
||||
import { CryptoGost, GostEngine } from "@wavesenterprise/crypto-gost-js/index.js";
|
||||
|
||||
/**
|
||||
* GOST Decrypt operation
|
||||
*/
|
||||
class GOSTDecrypt extends Operation {
|
||||
|
||||
/**
|
||||
* GOSTDecrypt constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "GOST Decrypt";
|
||||
this.module = "Ciphers";
|
||||
this.description = "The GOST block cipher (Magma), defined in the standard GOST 28147-89 (RFC 5830), is a Soviet and Russian government standard symmetric key block cipher with a block size of 64 bits. The original standard, published in 1989, did not give the cipher any name, but the most recent revision of the standard, GOST R 34.12-2015 (RFC 7801, RFC 8891), specifies that it may be referred to as Magma. The GOST hash function is based on this cipher. The new standard also specifies a new 128-bit block cipher called Kuznyechik.<br><br>Developed in the 1970s, the standard had been marked 'Top Secret' and then downgraded to 'Secret' in 1990. Shortly after the dissolution of the USSR, it was declassified and it was released to the public in 1994. GOST 28147 was a Soviet alternative to the United States standard algorithm, DES. Thus, the two are very similar in structure.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/GOST_(block_cipher)";
|
||||
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",
|
||||
type: "option",
|
||||
value: ["Hex", "Raw"]
|
||||
},
|
||||
{
|
||||
name: "Output type",
|
||||
type: "option",
|
||||
value: ["Raw", "Hex"]
|
||||
},
|
||||
{
|
||||
name: "Algorithm",
|
||||
type: "argSelector",
|
||||
value: [
|
||||
{
|
||||
name: "GOST 28147 (Magma, 1989)",
|
||||
off: [5],
|
||||
on: [6]
|
||||
},
|
||||
{
|
||||
name: "GOST R 34.12 (Kuznyechik, 2015)",
|
||||
on: [5],
|
||||
off: [6]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Block length",
|
||||
type: "option",
|
||||
value: ["64", "128"]
|
||||
},
|
||||
{
|
||||
name: "sBox",
|
||||
type: "option",
|
||||
value: ["E-TEST", "E-A", "E-B", "E-C", "E-D", "E-SC", "E-Z", "D-TEST", "D-A", "D-SC"]
|
||||
},
|
||||
{
|
||||
name: "Block mode",
|
||||
type: "option",
|
||||
value: ["ECB", "CFB", "OFB", "CTR", "CBC"]
|
||||
},
|
||||
{
|
||||
name: "Key meshing mode",
|
||||
type: "option",
|
||||
value: ["NO", "CP"]
|
||||
},
|
||||
{
|
||||
name: "Padding",
|
||||
type: "option",
|
||||
value: ["NO", "PKCS5", "ZERO", "RANDOM", "BIT"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [keyObj, ivObj, inputType, outputType, version, length, sBox, blockMode, keyMeshing, padding] = args;
|
||||
|
||||
const key = toHexFast(Utils.convertToByteArray(keyObj.string, keyObj.option));
|
||||
const iv = toHexFast(Utils.convertToByteArray(ivObj.string, ivObj.option));
|
||||
input = inputType === "Hex" ? input : toHexFast(Utils.strToArrayBuffer(input));
|
||||
|
||||
const versionNum = version === "GOST 28147 (Magma, 1989)" ? 1989 : 2015;
|
||||
const blockLength = versionNum === 1989 ? 64 : parseInt(length, 10);
|
||||
const sBoxVal = versionNum === 1989 ? sBox : null;
|
||||
|
||||
const algorithm = {
|
||||
version: versionNum,
|
||||
length: blockLength,
|
||||
mode: "ES",
|
||||
sBox: sBoxVal,
|
||||
block: blockMode,
|
||||
keyMeshing: keyMeshing,
|
||||
padding: padding
|
||||
};
|
||||
|
||||
try {
|
||||
const Hex = CryptoGost.coding.Hex;
|
||||
if (iv) algorithm.iv = Hex.decode(iv);
|
||||
|
||||
const cipher = GostEngine.getGostCipher(algorithm);
|
||||
const out = Hex.encode(cipher.decrypt(Hex.decode(key), Hex.decode(input)));
|
||||
|
||||
return outputType === "Hex" ? out : Utils.byteArrayToChars(fromHex(out));
|
||||
} catch (err) {
|
||||
throw new OperationError(err);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default GOSTDecrypt;
|
138
src/core/operations/GOSTEncrypt.mjs
Normal file
138
src/core/operations/GOSTEncrypt.mjs
Normal file
|
@ -0,0 +1,138 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import { toHexFast, fromHex } from "../lib/Hex.mjs";
|
||||
import { CryptoGost, GostEngine } from "@wavesenterprise/crypto-gost-js/index.js";
|
||||
|
||||
/**
|
||||
* GOST Encrypt operation
|
||||
*/
|
||||
class GOSTEncrypt extends Operation {
|
||||
|
||||
/**
|
||||
* GOSTEncrypt constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "GOST Encrypt";
|
||||
this.module = "Ciphers";
|
||||
this.description = "The GOST block cipher (Magma), defined in the standard GOST 28147-89 (RFC 5830), is a Soviet and Russian government standard symmetric key block cipher with a block size of 64 bits. The original standard, published in 1989, did not give the cipher any name, but the most recent revision of the standard, GOST R 34.12-2015 (RFC 7801, RFC 8891), specifies that it may be referred to as Magma. The GOST hash function is based on this cipher. The new standard also specifies a new 128-bit block cipher called Kuznyechik.<br><br>Developed in the 1970s, the standard had been marked 'Top Secret' and then downgraded to 'Secret' in 1990. Shortly after the dissolution of the USSR, it was declassified and it was released to the public in 1994. GOST 28147 was a Soviet alternative to the United States standard algorithm, DES. Thus, the two are very similar in structure.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/GOST_(block_cipher)";
|
||||
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",
|
||||
type: "option",
|
||||
value: ["Raw", "Hex"]
|
||||
},
|
||||
{
|
||||
name: "Output type",
|
||||
type: "option",
|
||||
value: ["Hex", "Raw"]
|
||||
},
|
||||
{
|
||||
name: "Algorithm",
|
||||
type: "argSelector",
|
||||
value: [
|
||||
{
|
||||
name: "GOST 28147 (Magma, 1989)",
|
||||
off: [5],
|
||||
on: [6]
|
||||
},
|
||||
{
|
||||
name: "GOST R 34.12 (Kuznyechik, 2015)",
|
||||
on: [5],
|
||||
off: [6]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Block length",
|
||||
type: "option",
|
||||
value: ["64", "128"]
|
||||
},
|
||||
{
|
||||
name: "sBox",
|
||||
type: "option",
|
||||
value: ["E-TEST", "E-A", "E-B", "E-C", "E-D", "E-SC", "E-Z", "D-TEST", "D-A", "D-SC"]
|
||||
},
|
||||
{
|
||||
name: "Block mode",
|
||||
type: "option",
|
||||
value: ["ECB", "CFB", "OFB", "CTR", "CBC"]
|
||||
},
|
||||
{
|
||||
name: "Key meshing mode",
|
||||
type: "option",
|
||||
value: ["NO", "CP"]
|
||||
},
|
||||
{
|
||||
name: "Padding",
|
||||
type: "option",
|
||||
value: ["NO", "PKCS5", "ZERO", "RANDOM", "BIT"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [keyObj, ivObj, inputType, outputType, version, length, sBox, blockMode, keyMeshing, padding] = args;
|
||||
|
||||
const key = toHexFast(Utils.convertToByteArray(keyObj.string, keyObj.option));
|
||||
const iv = toHexFast(Utils.convertToByteArray(ivObj.string, ivObj.option));
|
||||
input = inputType === "Hex" ? input : toHexFast(Utils.strToArrayBuffer(input));
|
||||
|
||||
const versionNum = version === "GOST 28147 (Magma, 1989)" ? 1989 : 2015;
|
||||
const blockLength = versionNum === 1989 ? 64 : parseInt(length, 10);
|
||||
const sBoxVal = versionNum === 1989 ? sBox : null;
|
||||
|
||||
const algorithm = {
|
||||
version: versionNum,
|
||||
length: blockLength,
|
||||
mode: "ES",
|
||||
sBox: sBoxVal,
|
||||
block: blockMode,
|
||||
keyMeshing: keyMeshing,
|
||||
padding: padding
|
||||
};
|
||||
|
||||
try {
|
||||
const Hex = CryptoGost.coding.Hex;
|
||||
if (iv) algorithm.iv = Hex.decode(iv);
|
||||
|
||||
const cipher = GostEngine.getGostCipher(algorithm);
|
||||
const out = Hex.encode(cipher.encrypt(Hex.decode(key), Hex.decode(input)));
|
||||
|
||||
return outputType === "Hex" ? out : Utils.byteArrayToChars(fromHex(out));
|
||||
} catch (err) {
|
||||
throw new OperationError(err);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default GOSTEncrypt;
|
|
@ -7,7 +7,7 @@
|
|||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import GostDigest from "../vendor/gost/gostDigest.mjs";
|
||||
import {toHexFast} from "../lib/Hex.mjs";
|
||||
import { toHexFast } from "../lib/Hex.mjs";
|
||||
|
||||
/**
|
||||
* GOST hash operation
|
||||
|
@ -20,7 +20,7 @@ class GOSTHash extends Operation {
|
|||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "GOST hash";
|
||||
this.name = "GOST Hash";
|
||||
this.module = "Hashing";
|
||||
this.description = "The GOST hash function, defined in the standards GOST R 34.11-94 and GOST 34.311-95 is a 256-bit cryptographic hash function. It was initially defined in the Russian national standard GOST R 34.11-94 <i>Information Technology – Cryptographic Information Security – Hash Function</i>. The equivalent standard used by other member-states of the CIS is GOST 34.311-95.<br><br>This function must not be confused with a different Streebog hash function, which is defined in the new revision of the standard GOST R 34.11-2012.<br><br>The GOST hash function is based on the GOST block cipher.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/GOST_(hash_function)";
|
||||
|
@ -28,20 +28,30 @@ class GOSTHash extends Operation {
|
|||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
"name": "S-Box",
|
||||
"type": "option",
|
||||
"value": [
|
||||
"D-A",
|
||||
"D-SC",
|
||||
"E-TEST",
|
||||
"E-A",
|
||||
"E-B",
|
||||
"E-C",
|
||||
"E-D",
|
||||
"E-SC",
|
||||
"E-Z",
|
||||
"D-TEST"
|
||||
name: "Algorithm",
|
||||
type: "argSelector",
|
||||
value: [
|
||||
{
|
||||
name: "GOST 28147 (1994)",
|
||||
off: [1],
|
||||
on: [2]
|
||||
},
|
||||
{
|
||||
name: "GOST R 34.11 (Streebog, 2012)",
|
||||
on: [1],
|
||||
off: [2]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Digest length",
|
||||
type: "option",
|
||||
value: ["256", "512"]
|
||||
},
|
||||
{
|
||||
name: "sBox",
|
||||
type: "option",
|
||||
value: ["E-TEST", "E-A", "E-B", "E-C", "E-D", "E-SC", "E-Z", "D-TEST", "D-A", "D-SC"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@ -52,13 +62,23 @@ class GOSTHash extends Operation {
|
|||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [version, length, sBox] = args;
|
||||
|
||||
const versionNum = version === "GOST 28147 (1994)" ? 1994 : 2012;
|
||||
const algorithm = {
|
||||
name: versionNum === 1994 ? "GOST 28147" : "GOST R 34.10",
|
||||
version: versionNum,
|
||||
mode: "HASH"
|
||||
};
|
||||
|
||||
if (versionNum === 1994) {
|
||||
algorithm.sBox = sBox;
|
||||
} else {
|
||||
algorithm.length = parseInt(length, 10);
|
||||
}
|
||||
|
||||
try {
|
||||
const sBox = args[1];
|
||||
const gostDigest = new GostDigest({
|
||||
name: "GOST R 34.11",
|
||||
version: 1994,
|
||||
sBox: sBox
|
||||
});
|
||||
const gostDigest = new GostDigest(algorithm);
|
||||
|
||||
return toHexFast(gostDigest.digest(input));
|
||||
} catch (err) {
|
||||
|
|
129
src/core/operations/GOSTKeyUnwrap.mjs
Normal file
129
src/core/operations/GOSTKeyUnwrap.mjs
Normal file
|
@ -0,0 +1,129 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import { toHexFast, fromHex } from "../lib/Hex.mjs";
|
||||
import { CryptoGost, GostEngine } from "@wavesenterprise/crypto-gost-js/index.js";
|
||||
|
||||
/**
|
||||
* GOST Key Unwrap operation
|
||||
*/
|
||||
class GOSTKeyUnwrap extends Operation {
|
||||
|
||||
/**
|
||||
* GOSTKeyUnwrap constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "GOST Key Unwrap";
|
||||
this.module = "Ciphers";
|
||||
this.description = "A decryptor for keys wrapped using one of the GOST block ciphers.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/GOST_(block_cipher)";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Key",
|
||||
type: "toggleString",
|
||||
value: "",
|
||||
toggleValues: ["Hex", "UTF8", "Latin1", "Base64"]
|
||||
},
|
||||
{
|
||||
name: "User Key Material",
|
||||
type: "toggleString",
|
||||
value: "",
|
||||
toggleValues: ["Hex", "UTF8", "Latin1", "Base64"]
|
||||
},
|
||||
{
|
||||
name: "Input type",
|
||||
type: "option",
|
||||
value: ["Hex", "Raw"]
|
||||
},
|
||||
{
|
||||
name: "Output type",
|
||||
type: "option",
|
||||
value: ["Raw", "Hex"]
|
||||
},
|
||||
{
|
||||
name: "Algorithm",
|
||||
type: "argSelector",
|
||||
value: [
|
||||
{
|
||||
name: "GOST 28147 (Magma, 1989)",
|
||||
off: [5],
|
||||
on: [6]
|
||||
},
|
||||
{
|
||||
name: "GOST R 34.12 (Kuznyechik, 2015)",
|
||||
on: [5],
|
||||
off: [6]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Block length",
|
||||
type: "option",
|
||||
value: ["64", "128"]
|
||||
},
|
||||
{
|
||||
name: "sBox",
|
||||
type: "option",
|
||||
value: ["E-TEST", "E-A", "E-B", "E-C", "E-D", "E-SC", "E-Z", "D-TEST", "D-A", "D-SC"]
|
||||
},
|
||||
{
|
||||
name: "Key wrapping",
|
||||
type: "option",
|
||||
value: ["NO", "CP", "SC"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [keyObj, ukmObj, inputType, outputType, version, length, sBox, keyWrapping] = args;
|
||||
|
||||
const key = toHexFast(Utils.convertToByteArray(keyObj.string, keyObj.option));
|
||||
const ukm = toHexFast(Utils.convertToByteArray(ukmObj.string, ukmObj.option));
|
||||
input = inputType === "Hex" ? input : toHexFast(Utils.strToArrayBuffer(input));
|
||||
|
||||
const versionNum = version === "GOST 28147 (Magma, 1989)" ? 1989 : 2015;
|
||||
const blockLength = versionNum === 1989 ? 64 : parseInt(length, 10);
|
||||
const sBoxVal = versionNum === 1989 ? sBox : null;
|
||||
|
||||
const algorithm = {
|
||||
version: versionNum,
|
||||
length: blockLength,
|
||||
mode: "KW",
|
||||
sBox: sBoxVal,
|
||||
keyWrapping: keyWrapping
|
||||
};
|
||||
|
||||
try {
|
||||
const Hex = CryptoGost.coding.Hex;
|
||||
algorithm.ukm = Hex.decode(ukm);
|
||||
|
||||
const cipher = GostEngine.getGostCipher(algorithm);
|
||||
const out = Hex.encode(cipher.unwrapKey(Hex.decode(key), Hex.decode(input)));
|
||||
|
||||
return outputType === "Hex" ? out : Utils.byteArrayToChars(fromHex(out));
|
||||
} catch (err) {
|
||||
if (err.toString().includes("Invalid typed array length")) {
|
||||
throw new OperationError("Incorrect input length. Must be a multiple of the block size.");
|
||||
}
|
||||
throw new OperationError(err);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default GOSTKeyUnwrap;
|
129
src/core/operations/GOSTKeyWrap.mjs
Normal file
129
src/core/operations/GOSTKeyWrap.mjs
Normal file
|
@ -0,0 +1,129 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import { toHexFast, fromHex } from "../lib/Hex.mjs";
|
||||
import { CryptoGost, GostEngine } from "@wavesenterprise/crypto-gost-js/index.js";
|
||||
|
||||
/**
|
||||
* GOST Key Wrap operation
|
||||
*/
|
||||
class GOSTKeyWrap extends Operation {
|
||||
|
||||
/**
|
||||
* GOSTKeyWrap constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "GOST Key Wrap";
|
||||
this.module = "Ciphers";
|
||||
this.description = "A key wrapping algorithm for protecting keys in untrusted storage using one of the GOST block cipers.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/GOST_(block_cipher)";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Key",
|
||||
type: "toggleString",
|
||||
value: "",
|
||||
toggleValues: ["Hex", "UTF8", "Latin1", "Base64"]
|
||||
},
|
||||
{
|
||||
name: "User Key Material",
|
||||
type: "toggleString",
|
||||
value: "",
|
||||
toggleValues: ["Hex", "UTF8", "Latin1", "Base64"]
|
||||
},
|
||||
{
|
||||
name: "Input type",
|
||||
type: "option",
|
||||
value: ["Raw", "Hex"]
|
||||
},
|
||||
{
|
||||
name: "Output type",
|
||||
type: "option",
|
||||
value: ["Hex", "Raw"]
|
||||
},
|
||||
{
|
||||
name: "Algorithm",
|
||||
type: "argSelector",
|
||||
value: [
|
||||
{
|
||||
name: "GOST 28147 (Magma, 1989)",
|
||||
off: [5],
|
||||
on: [6]
|
||||
},
|
||||
{
|
||||
name: "GOST R 34.12 (Kuznyechik, 2015)",
|
||||
on: [5],
|
||||
off: [6]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Block length",
|
||||
type: "option",
|
||||
value: ["64", "128"]
|
||||
},
|
||||
{
|
||||
name: "sBox",
|
||||
type: "option",
|
||||
value: ["E-TEST", "E-A", "E-B", "E-C", "E-D", "E-SC", "E-Z", "D-TEST", "D-A", "D-SC"]
|
||||
},
|
||||
{
|
||||
name: "Key wrapping",
|
||||
type: "option",
|
||||
value: ["NO", "CP", "SC"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [keyObj, ukmObj, inputType, outputType, version, length, sBox, keyWrapping] = args;
|
||||
|
||||
const key = toHexFast(Utils.convertToByteArray(keyObj.string, keyObj.option));
|
||||
const ukm = toHexFast(Utils.convertToByteArray(ukmObj.string, ukmObj.option));
|
||||
input = inputType === "Hex" ? input : toHexFast(Utils.strToArrayBuffer(input));
|
||||
|
||||
const versionNum = version === "GOST 28147 (Magma, 1989)" ? 1989 : 2015;
|
||||
const blockLength = versionNum === 1989 ? 64 : parseInt(length, 10);
|
||||
const sBoxVal = versionNum === 1989 ? sBox : null;
|
||||
|
||||
const algorithm = {
|
||||
version: versionNum,
|
||||
length: blockLength,
|
||||
mode: "KW",
|
||||
sBox: sBoxVal,
|
||||
keyWrapping: keyWrapping
|
||||
};
|
||||
|
||||
try {
|
||||
const Hex = CryptoGost.coding.Hex;
|
||||
algorithm.ukm = Hex.decode(ukm);
|
||||
|
||||
const cipher = GostEngine.getGostCipher(algorithm);
|
||||
const out = Hex.encode(cipher.wrapKey(Hex.decode(key), Hex.decode(input)));
|
||||
|
||||
return outputType === "Hex" ? out : Utils.byteArrayToChars(fromHex(out));
|
||||
} catch (err) {
|
||||
if (err.toString().includes("Invalid typed array length")) {
|
||||
throw new OperationError("Incorrect input length. Must be a multiple of the block size.");
|
||||
}
|
||||
throw new OperationError(err);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default GOSTKeyWrap;
|
129
src/core/operations/GOSTSign.mjs
Normal file
129
src/core/operations/GOSTSign.mjs
Normal file
|
@ -0,0 +1,129 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import { toHexFast, fromHex } from "../lib/Hex.mjs";
|
||||
import { CryptoGost, GostEngine } from "@wavesenterprise/crypto-gost-js/index.js";
|
||||
|
||||
/**
|
||||
* GOST Sign operation
|
||||
*/
|
||||
class GOSTSign extends Operation {
|
||||
|
||||
/**
|
||||
* GOSTSign constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "GOST Sign";
|
||||
this.module = "Ciphers";
|
||||
this.description = "Sign a plaintext message using one of the GOST block ciphers.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/GOST_(block_cipher)";
|
||||
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",
|
||||
type: "option",
|
||||
value: ["Raw", "Hex"]
|
||||
},
|
||||
{
|
||||
name: "Output type",
|
||||
type: "option",
|
||||
value: ["Hex", "Raw"]
|
||||
},
|
||||
{
|
||||
name: "Algorithm",
|
||||
type: "argSelector",
|
||||
value: [
|
||||
{
|
||||
name: "GOST 28147 (Magma, 1989)",
|
||||
off: [5],
|
||||
on: [6]
|
||||
},
|
||||
{
|
||||
name: "GOST R 34.12 (Kuznyechik, 2015)",
|
||||
on: [5],
|
||||
off: [6]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Block length",
|
||||
type: "option",
|
||||
value: ["64", "128"]
|
||||
},
|
||||
{
|
||||
name: "sBox",
|
||||
type: "option",
|
||||
value: ["E-TEST", "E-A", "E-B", "E-C", "E-D", "E-SC", "E-Z", "D-TEST", "D-A", "D-SC"]
|
||||
},
|
||||
{
|
||||
name: "MAC length",
|
||||
type: "number",
|
||||
value: 32,
|
||||
min: 8,
|
||||
max: 64,
|
||||
step: 8
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [keyObj, ivObj, inputType, outputType, version, length, sBox, macLength] = args;
|
||||
|
||||
const key = toHexFast(Utils.convertToByteArray(keyObj.string, keyObj.option));
|
||||
const iv = toHexFast(Utils.convertToByteArray(ivObj.string, ivObj.option));
|
||||
input = inputType === "Hex" ? input : toHexFast(Utils.strToArrayBuffer(input));
|
||||
|
||||
const versionNum = version === "GOST 28147 (Magma, 1989)" ? 1989 : 2015;
|
||||
const blockLength = versionNum === 1989 ? 64 : parseInt(length, 10);
|
||||
const sBoxVal = versionNum === 1989 ? sBox : null;
|
||||
|
||||
const algorithm = {
|
||||
version: versionNum,
|
||||
length: blockLength,
|
||||
mode: "MAC",
|
||||
sBox: sBoxVal,
|
||||
macLength: macLength
|
||||
};
|
||||
|
||||
try {
|
||||
const Hex = CryptoGost.coding.Hex;
|
||||
if (iv) algorithm.iv = Hex.decode(iv);
|
||||
|
||||
const cipher = GostEngine.getGostCipher(algorithm);
|
||||
const out = Hex.encode(cipher.sign(Hex.decode(key), Hex.decode(input)));
|
||||
|
||||
return outputType === "Hex" ? out : Utils.byteArrayToChars(fromHex(out));
|
||||
} catch (err) {
|
||||
throw new OperationError(err);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default GOSTSign;
|
123
src/core/operations/GOSTVerify.mjs
Normal file
123
src/core/operations/GOSTVerify.mjs
Normal file
|
@ -0,0 +1,123 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import { toHexFast } from "../lib/Hex.mjs";
|
||||
import { CryptoGost, GostEngine } from "@wavesenterprise/crypto-gost-js/index.js";
|
||||
|
||||
/**
|
||||
* GOST Verify operation
|
||||
*/
|
||||
class GOSTVerify extends Operation {
|
||||
|
||||
/**
|
||||
* GOSTVerify constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "GOST Verify";
|
||||
this.module = "Ciphers";
|
||||
this.description = "Verify the signature of a plaintext message using one of the GOST block ciphers. Enter the signature in the MAC field.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/GOST_(block_cipher)";
|
||||
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: "MAC",
|
||||
type: "toggleString",
|
||||
value: "",
|
||||
toggleValues: ["Hex", "UTF8", "Latin1", "Base64"]
|
||||
},
|
||||
{
|
||||
name: "Input type",
|
||||
type: "option",
|
||||
value: ["Raw", "Hex"]
|
||||
},
|
||||
{
|
||||
name: "Algorithm",
|
||||
type: "argSelector",
|
||||
value: [
|
||||
{
|
||||
name: "GOST 28147 (Magma, 1989)",
|
||||
off: [5],
|
||||
on: [6]
|
||||
},
|
||||
{
|
||||
name: "GOST R 34.12 (Kuznyechik, 2015)",
|
||||
on: [5],
|
||||
off: [6]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Block length",
|
||||
type: "option",
|
||||
value: ["64", "128"]
|
||||
},
|
||||
{
|
||||
name: "sBox",
|
||||
type: "option",
|
||||
value: ["E-TEST", "E-A", "E-B", "E-C", "E-D", "E-SC", "E-Z", "D-TEST", "D-A", "D-SC"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [keyObj, ivObj, macObj, inputType, version, length, sBox] = args;
|
||||
|
||||
const key = toHexFast(Utils.convertToByteArray(keyObj.string, keyObj.option));
|
||||
const iv = toHexFast(Utils.convertToByteArray(ivObj.string, ivObj.option));
|
||||
const mac = toHexFast(Utils.convertToByteArray(macObj.string, macObj.option));
|
||||
input = inputType === "Hex" ? input : toHexFast(Utils.strToArrayBuffer(input));
|
||||
|
||||
const versionNum = version === "GOST 28147 (Magma, 1989)" ? 1989 : 2015;
|
||||
const blockLength = versionNum === 1989 ? 64 : parseInt(length, 10);
|
||||
const sBoxVal = versionNum === 1989 ? sBox : null;
|
||||
|
||||
const algorithm = {
|
||||
version: versionNum,
|
||||
length: blockLength,
|
||||
mode: "MAC",
|
||||
sBox: sBoxVal,
|
||||
macLength: mac.length * 4
|
||||
};
|
||||
|
||||
try {
|
||||
const Hex = CryptoGost.coding.Hex;
|
||||
if (iv) algorithm.iv = Hex.decode(iv);
|
||||
|
||||
const cipher = GostEngine.getGostCipher(algorithm);
|
||||
const out = cipher.verify(Hex.decode(key), Hex.decode(mac), Hex.decode(input));
|
||||
|
||||
return out ? "The signature matches" : "The signature does not match";
|
||||
} catch (err) {
|
||||
throw new OperationError(err);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default GOSTVerify;
|
|
@ -108,7 +108,7 @@ class GenerateAllHashes extends Operation {
|
|||
{name: "BLAKE2s-256", algo: (new BLAKE2s), inputType: "arrayBuffer", params: ["256", "Hex", {string: "", option: "UTF8"}]},
|
||||
{name: "Streebog-256", algo: (new Streebog), inputType: "arrayBuffer", params: ["256"]},
|
||||
{name: "Streebog-512", algo: (new Streebog), inputType: "arrayBuffer", params: ["512"]},
|
||||
{name: "GOST", algo: (new GOSTHash), inputType: "arrayBuffer", params: ["D-A"]},
|
||||
{name: "GOST", algo: (new GOSTHash), inputType: "arrayBuffer", params: ["GOST 28147 (1994)", "256", "D-A"]},
|
||||
{name: "LM Hash", algo: (new LMHash), inputType: "str", params: []},
|
||||
{name: "NT Hash", algo: (new NTHash), inputType: "str", params: []},
|
||||
{name: "SSDEEP", algo: (new SSDEEP()), inputType: "str"},
|
||||
|
|
41
src/core/operations/LZNT1Decompress.mjs
Normal file
41
src/core/operations/LZNT1Decompress.mjs
Normal file
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* @author 0xThiebaut [thiebaut.dev]
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import {decompress} from "../lib/LZNT1.mjs";
|
||||
|
||||
/**
|
||||
* LZNT1 Decompress operation
|
||||
*/
|
||||
class LZNT1Decompress extends Operation {
|
||||
|
||||
/**
|
||||
* LZNT1 Decompress constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "LZNT1 Decompress";
|
||||
this.module = "Compression";
|
||||
this.description = "Decompresses data using the LZNT1 algorithm.<br><br>Similar to the Windows API <code>RtlDecompressBuffer</code>.";
|
||||
this.infoURL = "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-xca/5655f4a3-6ba4-489b-959f-e1f407c52f15";
|
||||
this.inputType = "byteArray";
|
||||
this.outputType = "byteArray";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {byteArray} input
|
||||
* @param {Object[]} args
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
run(input, args) {
|
||||
return decompress(input);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default LZNT1Decompress;
|
|
@ -20,7 +20,7 @@ class ParseASN1HexString extends Operation {
|
|||
|
||||
this.name = "Parse ASN.1 hex string";
|
||||
this.module = "PublicKey";
|
||||
this.description = "Abstract Syntax Notation One (ASN.1) is a standard and notation that describes rules and structures for representing, encoding, transmitting, and decoding data in telecommunications and computer networking.<br><br>This operation parses arbitrary ASN.1 data and presents the resulting tree.";
|
||||
this.description = "Abstract Syntax Notation One (ASN.1) is a standard and notation that describes rules and structures for representing, encoding, transmitting, and decoding data in telecommunications and computer networking.<br><br>This operation parses arbitrary ASN.1 data (encoded as an hex string: use the 'To Hex' operation if necessary) and presents the resulting tree.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Abstract_Syntax_Notation_One";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
|
|
|
@ -83,6 +83,10 @@ class RegularExpression extends Operation {
|
|||
name: "Strings",
|
||||
value: "[A-Za-z\\d/\\-:.,_$%\\x27\"()<>= !\\[\\]{}@]{4,}"
|
||||
},
|
||||
{
|
||||
name: "UUID (any version)",
|
||||
value: "[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}"
|
||||
},
|
||||
],
|
||||
"target": 1
|
||||
},
|
||||
|
|
|
@ -21,7 +21,7 @@ class SSDEEP extends Operation {
|
|||
this.name = "SSDEEP";
|
||||
this.module = "Crypto";
|
||||
this.description = "SSDEEP is a program for computing context triggered piecewise hashes (CTPH). Also called fuzzy hashes, CTPH can match inputs that have homologies. Such inputs have sequences of identical bytes in the same order, although bytes in between these sequences may be different in both content and length.<br><br>SSDEEP hashes are now widely used for simple identification purposes (e.g. the 'Basic Properties' section in VirusTotal). Although 'better' fuzzy hashes are available, SSDEEP is still one of the primary choices because of its speed and being a de facto standard.<br><br>This operation is fundamentally the same as the CTPH operation, however their outputs differ in format.";
|
||||
this.infoURL = "https://forensicswiki.xyz/wiki/index.php?title=Ssdeep";
|
||||
this.infoURL = "https://forensics.wiki/ssdeep";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
|
|
|
@ -28,7 +28,7 @@ class Streebog extends Operation {
|
|||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Size",
|
||||
"name": "Digest length",
|
||||
"type": "option",
|
||||
"value": ["256", "512"]
|
||||
}
|
||||
|
@ -41,13 +41,16 @@ class Streebog extends Operation {
|
|||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [length] = args;
|
||||
|
||||
const algorithm = {
|
||||
version: 2012,
|
||||
mode: "HASH",
|
||||
length: parseInt(length, 10)
|
||||
};
|
||||
|
||||
try {
|
||||
const length = parseInt(args[0], 10);
|
||||
const gostDigest = new GostDigest({
|
||||
name: "GOST R 34.11",
|
||||
version: 2012,
|
||||
length: length
|
||||
});
|
||||
const gostDigest = new GostDigest(algorithm);
|
||||
|
||||
return toHexFast(gostDigest.digest(input));
|
||||
} catch (err) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue