cyberchef 9.50.12 → 9.52.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -13,6 +13,12 @@ All major and minor version changes will be documented in this file. Details of
13
13
 
14
14
  ## Details
15
15
 
16
+ ### [9.52.0] - 2022-11-25
17
+ - Added 'ChaCha' operation [@joostrijneveld] | [#1466]
18
+
19
+ ### [9.51.0] - 2022-11-25
20
+ - Added 'CMAC' operation [@mikecat] | [#1457]
21
+
16
22
  ### [9.50.0] - 2022-11-25
17
23
  - Added 'Shuffle' operation [@mikecat] | [#1472]
18
24
 
@@ -327,6 +333,8 @@ All major and minor version changes will be documented in this file. Details of
327
333
 
328
334
 
329
335
 
336
+ [9.52.0]: https://github.com/gchq/CyberChef/releases/tag/v9.52.0
337
+ [9.51.0]: https://github.com/gchq/CyberChef/releases/tag/v9.51.0
330
338
  [9.50.0]: https://github.com/gchq/CyberChef/releases/tag/v9.50.0
331
339
  [9.49.0]: https://github.com/gchq/CyberChef/releases/tag/v9.49.0
332
340
  [9.48.0]: https://github.com/gchq/CyberChef/releases/tag/v9.48.0
@@ -467,6 +475,7 @@ All major and minor version changes will be documented in this file. Details of
467
475
  [@thomasleplus]: https://github.com/thomasleplus
468
476
  [@valdelaseras]: https://github.com/valdelaseras
469
477
  [@brun0ne]: https://github.com/brun0ne
478
+ [@joostrijneveld]: https://github.com/joostrijneveld
470
479
 
471
480
  [8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7
472
481
  [9a33498]: https://github.com/gchq/CyberChef/commit/9a33498fed26a8df9c9f35f39a78a174bf50a513
@@ -573,4 +582,6 @@ All major and minor version changes will be documented in this file. Details of
573
582
  [#1421]: https://github.com/gchq/CyberChef/pull/1421
574
583
  [#1427]: https://github.com/gchq/CyberChef/pull/1427
575
584
  [#1472]: https://github.com/gchq/CyberChef/pull/1472
585
+ [#1457]: https://github.com/gchq/CyberChef/pull/1457
586
+ [#1466]: https://github.com/gchq/CyberChef/pull/1466
576
587
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cyberchef",
3
- "version": "9.50.12",
3
+ "version": "9.52.1",
4
4
  "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
5
5
  "author": "n1474335 <n1474335@gmail.com>",
6
6
  "homepage": "https://gchq.github.io/CyberChef",
@@ -27,6 +27,7 @@ class Ingredient {
27
27
  this.toggleValues = [];
28
28
  this.target = null;
29
29
  this.defaultIndex = 0;
30
+ this.maxLength = null;
30
31
  this.min = null;
31
32
  this.max = null;
32
33
  this.step = 1;
@@ -53,6 +54,7 @@ class Ingredient {
53
54
  this.toggleValues = ingredientConfig.toggleValues;
54
55
  this.target = typeof ingredientConfig.target !== "undefined" ? ingredientConfig.target : null;
55
56
  this.defaultIndex = typeof ingredientConfig.defaultIndex !== "undefined" ? ingredientConfig.defaultIndex : 0;
57
+ this.maxLength = ingredientConfig.maxLength || null;
56
58
  this.min = ingredientConfig.min;
57
59
  this.max = ingredientConfig.max;
58
60
  this.step = ingredientConfig.step;
@@ -184,6 +184,7 @@ class Operation {
184
184
  if (ing.disabled) conf.disabled = ing.disabled;
185
185
  if (ing.target) conf.target = ing.target;
186
186
  if (ing.defaultIndex) conf.defaultIndex = ing.defaultIndex;
187
+ if (ing.maxLength) conf.maxLength = ing.maxLength;
187
188
  if (typeof ing.min === "number") conf.min = ing.min;
188
189
  if (typeof ing.max === "number") conf.max = ing.max;
189
190
  if (ing.step) conf.step = ing.step;
@@ -382,6 +382,70 @@ class Utils {
382
382
  }
383
383
 
384
384
 
385
+ /**
386
+ * Converts a byte array to an integer.
387
+ *
388
+ * @param {byteArray} byteArray
389
+ * @param {string} byteorder - "little" or "big"
390
+ * @returns {integer}
391
+ *
392
+ * @example
393
+ * // returns 67305985
394
+ * Utils.byteArrayToInt([1, 2, 3, 4], "little");
395
+ *
396
+ * // returns 16909060
397
+ * Utils.byteArrayToInt([1, 2, 3, 4], "big");
398
+ */
399
+ static byteArrayToInt(byteArray, byteorder) {
400
+ let value = 0;
401
+ if (byteorder === "big") {
402
+ for (let i = 0; i < byteArray.length; i++) {
403
+ value = (value * 256) + byteArray[i];
404
+ }
405
+ } else {
406
+ for (let i = byteArray.length - 1; i >= 0; i--) {
407
+ value = (value * 256) + byteArray[i];
408
+ }
409
+ }
410
+ return value;
411
+ }
412
+
413
+
414
+ /**
415
+ * Converts an integer to a byte array of {length} bytes.
416
+ *
417
+ * @param {integer} value
418
+ * @param {integer} length
419
+ * @param {string} byteorder - "little" or "big"
420
+ * @returns {byteArray}
421
+ *
422
+ * @example
423
+ * // returns [5, 255, 109, 1]
424
+ * Utils.intToByteArray(23985925, 4, "little");
425
+ *
426
+ * // returns [1, 109, 255, 5]
427
+ * Utils.intToByteArray(23985925, 4, "big");
428
+ *
429
+ * // returns [0, 0, 0, 0, 1, 109, 255, 5]
430
+ * Utils.intToByteArray(23985925, 8, "big");
431
+ */
432
+ static intToByteArray(value, length, byteorder) {
433
+ const arr = new Array(length);
434
+ if (byteorder === "little") {
435
+ for (let i = 0; i < length; i++) {
436
+ arr[i] = value & 0xFF;
437
+ value = value >>> 8;
438
+ }
439
+ } else {
440
+ for (let i = length - 1; i >= 0; i--) {
441
+ arr[i] = value & 0xFF;
442
+ value = value >>> 8;
443
+ }
444
+ }
445
+ return arr;
446
+ }
447
+
448
+
385
449
  /**
386
450
  * Converts a string to an ArrayBuffer.
387
451
  * Treats the string as UTF-8 if any values are over 255.
@@ -75,6 +75,7 @@
75
75
  "AES Decrypt",
76
76
  "Blowfish Encrypt",
77
77
  "Blowfish Decrypt",
78
+ "ChaCha",
78
79
  "DES Encrypt",
79
80
  "DES Decrypt",
80
81
  "Triple DES Encrypt",
@@ -368,6 +369,7 @@
368
369
  "Compare SSDEEP hashes",
369
370
  "Compare CTPH hashes",
370
371
  "HMAC",
372
+ "CMAC",
371
373
  "Bcrypt",
372
374
  "Bcrypt compare",
373
375
  "Bcrypt parse",
@@ -1330,6 +1330,36 @@
1330
1330
  "manualBake": false,
1331
1331
  "args": []
1332
1332
  },
1333
+ "CMAC": {
1334
+ "module": "Crypto",
1335
+ "description": "CMAC is a block-cipher based message authentication code algorithm.<br><br>RFC4493 defines AES-CMAC that uses AES encryption with a 128-bit key.<br>NIST SP 800-38B suggests usages of AES with other key lengths and Triple DES.",
1336
+ "infoURL": "https://wikipedia.org/wiki/CMAC",
1337
+ "inputType": "ArrayBuffer",
1338
+ "outputType": "string",
1339
+ "flowControl": false,
1340
+ "manualBake": false,
1341
+ "args": [
1342
+ {
1343
+ "name": "Key",
1344
+ "type": "toggleString",
1345
+ "value": "",
1346
+ "toggleValues": [
1347
+ "Hex",
1348
+ "UTF8",
1349
+ "Latin1",
1350
+ "Base64"
1351
+ ]
1352
+ },
1353
+ {
1354
+ "name": "Encryption algorithm",
1355
+ "type": "option",
1356
+ "value": [
1357
+ "AES",
1358
+ "Triple DES"
1359
+ ]
1360
+ }
1361
+ ]
1362
+ },
1333
1363
  "CRC-16 Checksum": {
1334
1364
  "module": "Crypto",
1335
1365
  "description": "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.<br><br>The CRC was invented by W. Wesley Peterson in 1961.",
@@ -1533,6 +1563,71 @@
1533
1563
  "manualBake": false,
1534
1564
  "args": []
1535
1565
  },
1566
+ "ChaCha": {
1567
+ "module": "Default",
1568
+ "description": "ChaCha is a stream cipher designed by Daniel J. Bernstein. It is a variant of the Salsa stream cipher. Several parameterizations exist; 'ChaCha' may refer to the original construction, or to the variant as described in RFC-8439. ChaCha is often used with Poly1305, in the ChaCha20-Poly1305 AEAD construction.<br><br><b>Key:</b> ChaCha uses a key of 16 or 32 bytes (128 or 256 bits).<br><br><b>Nonce:</b> ChaCha uses a nonce of 8 or 12 bytes (64 or 96 bits).<br><br><b>Counter:</b> ChaCha uses a counter of 4 or 8 bytes (32 or 64 bits); together, the nonce and counter must add up to 16 bytes. The counter starts at zero at the start of the keystream, and is incremented at every 64 bytes.",
1569
+ "infoURL": "https://wikipedia.org/wiki/Salsa20#ChaCha_variant",
1570
+ "inputType": "string",
1571
+ "outputType": "string",
1572
+ "flowControl": false,
1573
+ "manualBake": false,
1574
+ "args": [
1575
+ {
1576
+ "name": "Key",
1577
+ "type": "toggleString",
1578
+ "value": "",
1579
+ "toggleValues": [
1580
+ "Hex",
1581
+ "UTF8",
1582
+ "Latin1",
1583
+ "Base64"
1584
+ ]
1585
+ },
1586
+ {
1587
+ "name": "Nonce",
1588
+ "type": "toggleString",
1589
+ "value": "",
1590
+ "toggleValues": [
1591
+ "Hex",
1592
+ "UTF8",
1593
+ "Latin1",
1594
+ "Base64",
1595
+ "Integer"
1596
+ ]
1597
+ },
1598
+ {
1599
+ "name": "Counter",
1600
+ "type": "number",
1601
+ "value": 0,
1602
+ "min": 0
1603
+ },
1604
+ {
1605
+ "name": "Rounds",
1606
+ "type": "option",
1607
+ "value": [
1608
+ "20",
1609
+ "12",
1610
+ "8"
1611
+ ]
1612
+ },
1613
+ {
1614
+ "name": "Input",
1615
+ "type": "option",
1616
+ "value": [
1617
+ "Hex",
1618
+ "Raw"
1619
+ ]
1620
+ },
1621
+ {
1622
+ "name": "Output",
1623
+ "type": "option",
1624
+ "value": [
1625
+ "Raw",
1626
+ "Hex"
1627
+ ]
1628
+ }
1629
+ ]
1630
+ },
1536
1631
  "Change IP format": {
1537
1632
  "module": "Default",
1538
1633
  "description": "Convert an IP address from one format to another, e.g. <code>172.20.23.54</code> to <code>ac141736</code>",
@@ -6065,6 +6160,12 @@
6065
6160
  "name": "Remove non-alphabet chars",
6066
6161
  "type": "boolean",
6067
6162
  "value": true
6163
+ },
6164
+ {
6165
+ "name": "All-zero group char",
6166
+ "type": "binaryShortString",
6167
+ "value": "z",
6168
+ "maxLength": 1
6068
6169
  }
6069
6170
  ],
6070
6171
  "checks": [
@@ -10,6 +10,7 @@ import AnalyseHash from "../../operations/AnalyseHash.mjs";
10
10
  import Bcrypt from "../../operations/Bcrypt.mjs";
11
11
  import BcryptCompare from "../../operations/BcryptCompare.mjs";
12
12
  import BcryptParse from "../../operations/BcryptParse.mjs";
13
+ import CMAC from "../../operations/CMAC.mjs";
13
14
  import CRC16Checksum from "../../operations/CRC16Checksum.mjs";
14
15
  import CRC32Checksum from "../../operations/CRC32Checksum.mjs";
15
16
  import CRC8Checksum from "../../operations/CRC8Checksum.mjs";
@@ -63,6 +64,7 @@ OpModules.Crypto = {
63
64
  "Bcrypt": Bcrypt,
64
65
  "Bcrypt compare": BcryptCompare,
65
66
  "Bcrypt parse": BcryptParse,
67
+ "CMAC": CMAC,
66
68
  "CRC-16 Checksum": CRC16Checksum,
67
69
  "CRC-32 Checksum": CRC32Checksum,
68
70
  "CRC-8 Checksum": CRC8Checksum,
@@ -14,6 +14,7 @@ import BitShiftLeft from "../../operations/BitShiftLeft.mjs";
14
14
  import BitShiftRight from "../../operations/BitShiftRight.mjs";
15
15
  import CSVToJSON from "../../operations/CSVToJSON.mjs";
16
16
  import CartesianProduct from "../../operations/CartesianProduct.mjs";
17
+ import ChaCha from "../../operations/ChaCha.mjs";
17
18
  import ChangeIPFormat from "../../operations/ChangeIPFormat.mjs";
18
19
  import ChiSquare from "../../operations/ChiSquare.mjs";
19
20
  import Comment from "../../operations/Comment.mjs";
@@ -188,6 +189,7 @@ OpModules.Default = {
188
189
  "Bit shift right": BitShiftRight,
189
190
  "CSV to JSON": CSVToJSON,
190
191
  "Cartesian Product": CartesianProduct,
192
+ "ChaCha": ChaCha,
191
193
  "Change IP format": ChangeIPFormat,
192
194
  "Chi Square": ChiSquare,
193
195
  "Comment": Comment,
@@ -0,0 +1,149 @@
1
+ /**
2
+ * @author mikecat
3
+ * @copyright Crown Copyright 2022
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ import Operation from "../Operation.mjs";
8
+ import Utils from "../Utils.mjs";
9
+ import forge from "node-forge";
10
+ import { toHexFast } from "../lib/Hex.mjs";
11
+ import OperationError from "../errors/OperationError.mjs";
12
+
13
+ /**
14
+ * CMAC operation
15
+ */
16
+ class CMAC extends Operation {
17
+
18
+ /**
19
+ * CMAC constructor
20
+ */
21
+ constructor() {
22
+ super();
23
+
24
+ this.name = "CMAC";
25
+ this.module = "Crypto";
26
+ this.description = "CMAC is a block-cipher based message authentication code algorithm.<br><br>RFC4493 defines AES-CMAC that uses AES encryption with a 128-bit key.<br>NIST SP 800-38B suggests usages of AES with other key lengths and Triple DES.";
27
+ this.infoURL = "https://wikipedia.org/wiki/CMAC";
28
+ this.inputType = "ArrayBuffer";
29
+ this.outputType = "string";
30
+ this.args = [
31
+ {
32
+ "name": "Key",
33
+ "type": "toggleString",
34
+ "value": "",
35
+ "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
36
+ },
37
+ {
38
+ "name": "Encryption algorithm",
39
+ "type": "option",
40
+ "value": ["AES", "Triple DES"]
41
+ }
42
+ ];
43
+ }
44
+
45
+ /**
46
+ * @param {ArrayBuffer} input
47
+ * @param {Object[]} args
48
+ * @returns {string}
49
+ */
50
+ run(input, args) {
51
+ const key = Utils.convertToByteString(args[0].string, args[0].option);
52
+ const algo = args[1];
53
+
54
+ const info = (function() {
55
+ switch (algo) {
56
+ case "AES":
57
+ if (key.length !== 16 && key.length !== 24 && key.length !== 32) {
58
+ throw new OperationError("The key for AES must be either 16, 24, or 32 bytes (currently " + key.length + " bytes)");
59
+ }
60
+ return {
61
+ "algorithm": "AES-ECB",
62
+ "key": key,
63
+ "blockSize": 16,
64
+ "Rb": new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x87]),
65
+ };
66
+ case "Triple DES":
67
+ if (key.length !== 16 && key.length !== 24) {
68
+ throw new OperationError("The key for Triple DES must be 16 or 24 bytes (currently " + key.length + " bytes)");
69
+ }
70
+ return {
71
+ "algorithm": "3DES-ECB",
72
+ "key": key.length === 16 ? key + key.substring(0, 8) : key,
73
+ "blockSize": 8,
74
+ "Rb": new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0x1b]),
75
+ };
76
+ default:
77
+ throw new OperationError("Undefined encryption algorithm");
78
+ }
79
+ })();
80
+
81
+ const xor = function(a, b, out) {
82
+ if (!out) out = new Uint8Array(a.length);
83
+ for (let i = 0; i < a.length; i++) {
84
+ out[i] = a[i] ^ b[i];
85
+ }
86
+ return out;
87
+ };
88
+
89
+ const leftShift1 = function(a) {
90
+ const out = new Uint8Array(a.length);
91
+ let carry = 0;
92
+ for (let i = a.length - 1; i >= 0; i--) {
93
+ out[i] = (a[i] << 1) | carry;
94
+ carry = a[i] >> 7;
95
+ }
96
+ return out;
97
+ };
98
+
99
+ const cipher = forge.cipher.createCipher(info.algorithm, info.key);
100
+ const encrypt = function(a, out) {
101
+ if (!out) out = new Uint8Array(a.length);
102
+ cipher.start();
103
+ cipher.update(forge.util.createBuffer(a));
104
+ cipher.finish();
105
+ const cipherText = cipher.output.getBytes();
106
+ for (let i = 0; i < a.length; i++) {
107
+ out[i] = cipherText.charCodeAt(i);
108
+ }
109
+ return out;
110
+ };
111
+
112
+ const L = encrypt(new Uint8Array(info.blockSize));
113
+ const K1 = leftShift1(L);
114
+ if (L[0] & 0x80) xor(K1, info.Rb, K1);
115
+ const K2 = leftShift1(K1);
116
+ if (K1[0] & 0x80) xor(K2, info.Rb, K2);
117
+
118
+ const n = Math.ceil(input.byteLength / info.blockSize);
119
+ const lastBlock = (function() {
120
+ if (n === 0) {
121
+ const data = new Uint8Array(K2);
122
+ data[0] ^= 0x80;
123
+ return data;
124
+ }
125
+ const inputLast = new Uint8Array(input, info.blockSize * (n - 1));
126
+ if (inputLast.length === info.blockSize) {
127
+ return xor(inputLast, K1, inputLast);
128
+ } else {
129
+ const data = new Uint8Array(info.blockSize);
130
+ data.set(inputLast, 0);
131
+ data[inputLast.length] = 0x80;
132
+ return xor(data, K2, data);
133
+ }
134
+ })();
135
+
136
+ const X = new Uint8Array(info.blockSize);
137
+ const Y = new Uint8Array(info.blockSize);
138
+ for (let i = 0; i < n - 1; i++) {
139
+ xor(X, new Uint8Array(input, info.blockSize * i, info.blockSize), Y);
140
+ encrypt(Y, X);
141
+ }
142
+ xor(lastBlock, X, Y);
143
+ const T = encrypt(Y);
144
+ return toHexFast(T);
145
+ }
146
+
147
+ }
148
+
149
+ export default CMAC;