cyberchef 9.52.1 → 9.54.0

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.54.0] - 2022-11-25
17
+ - Added 'Rabbit' operation [@mikecat] | [#1450]
18
+
19
+ ### [9.53.0] - 2022-11-25
20
+ - Added 'AES Key Wrap' and 'AES Key Unwrap' operations [@mikecat] | [#1456]
21
+
16
22
  ### [9.52.0] - 2022-11-25
17
23
  - Added 'ChaCha' operation [@joostrijneveld] | [#1466]
18
24
 
@@ -333,6 +339,8 @@ All major and minor version changes will be documented in this file. Details of
333
339
 
334
340
 
335
341
 
342
+ [9.54.0]: https://github.com/gchq/CyberChef/releases/tag/v9.54.0
343
+ [9.53.0]: https://github.com/gchq/CyberChef/releases/tag/v9.53.0
336
344
  [9.52.0]: https://github.com/gchq/CyberChef/releases/tag/v9.52.0
337
345
  [9.51.0]: https://github.com/gchq/CyberChef/releases/tag/v9.51.0
338
346
  [9.50.0]: https://github.com/gchq/CyberChef/releases/tag/v9.50.0
@@ -584,4 +592,6 @@ All major and minor version changes will be documented in this file. Details of
584
592
  [#1472]: https://github.com/gchq/CyberChef/pull/1472
585
593
  [#1457]: https://github.com/gchq/CyberChef/pull/1457
586
594
  [#1466]: https://github.com/gchq/CyberChef/pull/1466
595
+ [#1456]: https://github.com/gchq/CyberChef/pull/1456
596
+ [#1450]: https://github.com/gchq/CyberChef/pull/1450
587
597
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cyberchef",
3
- "version": "9.52.1",
3
+ "version": "9.54.0",
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",
@@ -75,7 +75,6 @@
75
75
  "AES Decrypt",
76
76
  "Blowfish Encrypt",
77
77
  "Blowfish Decrypt",
78
- "ChaCha",
79
78
  "DES Encrypt",
80
79
  "DES Decrypt",
81
80
  "Triple DES Encrypt",
@@ -86,6 +85,8 @@
86
85
  "RC2 Decrypt",
87
86
  "RC4",
88
87
  "RC4 Drop",
88
+ "ChaCha",
89
+ "Rabbit",
89
90
  "SM4 Encrypt",
90
91
  "SM4 Decrypt",
91
92
  "ROT13",
@@ -125,6 +126,8 @@
125
126
  "JWT Decode",
126
127
  "Citrix CTX1 Encode",
127
128
  "Citrix CTX1 Decode",
129
+ "AES Key Wrap",
130
+ "AES Key Unwrap",
128
131
  "Pseudo-Random Number Generator",
129
132
  "Enigma",
130
133
  "Bombe",
@@ -348,6 +348,104 @@
348
348
  }
349
349
  ]
350
350
  },
351
+ "AES Key Unwrap": {
352
+ "module": "Ciphers",
353
+ "description": "Decryptor for a key wrapping algorithm defined in RFC3394, which is used to protect keys in untrusted storage or communications, using AES.<br><br>This algorithm uses an AES key (KEK: key-encryption key) and a 64-bit IV to decrypt 64-bit blocks.",
354
+ "infoURL": "https://wikipedia.org/wiki/Key_wrap",
355
+ "inputType": "string",
356
+ "outputType": "string",
357
+ "flowControl": false,
358
+ "manualBake": false,
359
+ "args": [
360
+ {
361
+ "name": "Key (KEK)",
362
+ "type": "toggleString",
363
+ "value": "",
364
+ "toggleValues": [
365
+ "Hex",
366
+ "UTF8",
367
+ "Latin1",
368
+ "Base64"
369
+ ]
370
+ },
371
+ {
372
+ "name": "IV",
373
+ "type": "toggleString",
374
+ "value": "a6a6a6a6a6a6a6a6",
375
+ "toggleValues": [
376
+ "Hex",
377
+ "UTF8",
378
+ "Latin1",
379
+ "Base64"
380
+ ]
381
+ },
382
+ {
383
+ "name": "Input",
384
+ "type": "option",
385
+ "value": [
386
+ "Hex",
387
+ "Raw"
388
+ ]
389
+ },
390
+ {
391
+ "name": "Output",
392
+ "type": "option",
393
+ "value": [
394
+ "Hex",
395
+ "Raw"
396
+ ]
397
+ }
398
+ ]
399
+ },
400
+ "AES Key Wrap": {
401
+ "module": "Ciphers",
402
+ "description": "A key wrapping algorithm defined in RFC3394, which is used to protect keys in untrusted storage or communications, using AES.<br><br>This algorithm uses an AES key (KEK: key-encryption key) and a 64-bit IV to encrypt 64-bit blocks.",
403
+ "infoURL": "https://wikipedia.org/wiki/Key_wrap",
404
+ "inputType": "string",
405
+ "outputType": "string",
406
+ "flowControl": false,
407
+ "manualBake": false,
408
+ "args": [
409
+ {
410
+ "name": "Key (KEK)",
411
+ "type": "toggleString",
412
+ "value": "",
413
+ "toggleValues": [
414
+ "Hex",
415
+ "UTF8",
416
+ "Latin1",
417
+ "Base64"
418
+ ]
419
+ },
420
+ {
421
+ "name": "IV",
422
+ "type": "toggleString",
423
+ "value": "a6a6a6a6a6a6a6a6",
424
+ "toggleValues": [
425
+ "Hex",
426
+ "UTF8",
427
+ "Latin1",
428
+ "Base64"
429
+ ]
430
+ },
431
+ {
432
+ "name": "Input",
433
+ "type": "option",
434
+ "value": [
435
+ "Hex",
436
+ "Raw"
437
+ ]
438
+ },
439
+ {
440
+ "name": "Output",
441
+ "type": "option",
442
+ "value": [
443
+ "Hex",
444
+ "Raw"
445
+ ]
446
+ }
447
+ ]
448
+ },
351
449
  "AND": {
352
450
  "module": "Default",
353
451
  "description": "AND the input with the given key.<br>e.g. <code>fe023da5</code>",
@@ -10747,6 +10845,63 @@
10747
10845
  }
10748
10846
  ]
10749
10847
  },
10848
+ "Rabbit": {
10849
+ "module": "Ciphers",
10850
+ "description": "Rabbit is a high-speed stream cipher introduced in 2003 and defined in RFC 4503.<br><br>The cipher uses a 128-bit key and an optional 64-bit initialization vector (IV).<br><br>big-endian: based on RFC4503 and RFC3447<br>little-endian: compatible with Crypto++",
10851
+ "infoURL": "https://wikipedia.org/wiki/Rabbit_(cipher)",
10852
+ "inputType": "string",
10853
+ "outputType": "string",
10854
+ "flowControl": false,
10855
+ "manualBake": false,
10856
+ "args": [
10857
+ {
10858
+ "name": "Key",
10859
+ "type": "toggleString",
10860
+ "value": "",
10861
+ "toggleValues": [
10862
+ "Hex",
10863
+ "UTF8",
10864
+ "Latin1",
10865
+ "Base64"
10866
+ ]
10867
+ },
10868
+ {
10869
+ "name": "IV",
10870
+ "type": "toggleString",
10871
+ "value": "",
10872
+ "toggleValues": [
10873
+ "Hex",
10874
+ "UTF8",
10875
+ "Latin1",
10876
+ "Base64"
10877
+ ]
10878
+ },
10879
+ {
10880
+ "name": "Endianness",
10881
+ "type": "option",
10882
+ "value": [
10883
+ "Big",
10884
+ "Little"
10885
+ ]
10886
+ },
10887
+ {
10888
+ "name": "Input",
10889
+ "type": "option",
10890
+ "value": [
10891
+ "Raw",
10892
+ "Hex"
10893
+ ]
10894
+ },
10895
+ {
10896
+ "name": "Output",
10897
+ "type": "option",
10898
+ "value": [
10899
+ "Raw",
10900
+ "Hex"
10901
+ ]
10902
+ }
10903
+ ]
10904
+ },
10750
10905
  "Rail Fence Cipher Decode": {
10751
10906
  "module": "Ciphers",
10752
10907
  "description": "Decodes Strings that were created using the Rail fence Cipher provided a key and an offset",
@@ -9,6 +9,8 @@ import A1Z26CipherDecode from "../../operations/A1Z26CipherDecode.mjs";
9
9
  import A1Z26CipherEncode from "../../operations/A1Z26CipherEncode.mjs";
10
10
  import AESDecrypt from "../../operations/AESDecrypt.mjs";
11
11
  import AESEncrypt from "../../operations/AESEncrypt.mjs";
12
+ import AESKeyUnwrap from "../../operations/AESKeyUnwrap.mjs";
13
+ import AESKeyWrap from "../../operations/AESKeyWrap.mjs";
12
14
  import AffineCipherDecode from "../../operations/AffineCipherDecode.mjs";
13
15
  import AffineCipherEncode from "../../operations/AffineCipherEncode.mjs";
14
16
  import AtbashCipher from "../../operations/AtbashCipher.mjs";
@@ -33,6 +35,7 @@ import RSADecrypt from "../../operations/RSADecrypt.mjs";
33
35
  import RSAEncrypt from "../../operations/RSAEncrypt.mjs";
34
36
  import RSASign from "../../operations/RSASign.mjs";
35
37
  import RSAVerify from "../../operations/RSAVerify.mjs";
38
+ import Rabbit from "../../operations/Rabbit.mjs";
36
39
  import RailFenceCipherDecode from "../../operations/RailFenceCipherDecode.mjs";
37
40
  import RailFenceCipherEncode from "../../operations/RailFenceCipherEncode.mjs";
38
41
  import SM4Decrypt from "../../operations/SM4Decrypt.mjs";
@@ -49,6 +52,8 @@ OpModules.Ciphers = {
49
52
  "A1Z26 Cipher Encode": A1Z26CipherEncode,
50
53
  "AES Decrypt": AESDecrypt,
51
54
  "AES Encrypt": AESEncrypt,
55
+ "AES Key Unwrap": AESKeyUnwrap,
56
+ "AES Key Wrap": AESKeyWrap,
52
57
  "Affine Cipher Decode": AffineCipherDecode,
53
58
  "Affine Cipher Encode": AffineCipherEncode,
54
59
  "Atbash Cipher": AtbashCipher,
@@ -73,6 +78,7 @@ OpModules.Ciphers = {
73
78
  "RSA Encrypt": RSAEncrypt,
74
79
  "RSA Sign": RSASign,
75
80
  "RSA Verify": RSAVerify,
81
+ "Rabbit": Rabbit,
76
82
  "Rail Fence Cipher Decode": RailFenceCipherDecode,
77
83
  "Rail Fence Cipher Encode": RailFenceCipherEncode,
78
84
  "SM4 Decrypt": SM4Decrypt,
@@ -0,0 +1,128 @@
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 { toHexFast } from "../lib/Hex.mjs";
10
+ import forge from "node-forge";
11
+ import OperationError from "../errors/OperationError.mjs";
12
+
13
+ /**
14
+ * AES Key Unwrap operation
15
+ */
16
+ class AESKeyUnwrap extends Operation {
17
+
18
+ /**
19
+ * AESKeyUnwrap constructor
20
+ */
21
+ constructor() {
22
+ super();
23
+
24
+ this.name = "AES Key Unwrap";
25
+ this.module = "Ciphers";
26
+ this.description = "Decryptor for a key wrapping algorithm defined in RFC3394, which is used to protect keys in untrusted storage or communications, using AES.<br><br>This algorithm uses an AES key (KEK: key-encryption key) and a 64-bit IV to decrypt 64-bit blocks.";
27
+ this.infoURL = "https://wikipedia.org/wiki/Key_wrap";
28
+ this.inputType = "string";
29
+ this.outputType = "string";
30
+ this.args = [
31
+ {
32
+ "name": "Key (KEK)",
33
+ "type": "toggleString",
34
+ "value": "",
35
+ "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
36
+ },
37
+ {
38
+ "name": "IV",
39
+ "type": "toggleString",
40
+ "value": "a6a6a6a6a6a6a6a6",
41
+ "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
42
+ },
43
+ {
44
+ "name": "Input",
45
+ "type": "option",
46
+ "value": ["Hex", "Raw"]
47
+ },
48
+ {
49
+ "name": "Output",
50
+ "type": "option",
51
+ "value": ["Hex", "Raw"]
52
+ },
53
+ ];
54
+ }
55
+
56
+ /**
57
+ * @param {string} input
58
+ * @param {Object[]} args
59
+ * @returns {string}
60
+ */
61
+ run(input, args) {
62
+ const kek = Utils.convertToByteString(args[0].string, args[0].option),
63
+ iv = Utils.convertToByteString(args[1].string, args[1].option),
64
+ inputType = args[2],
65
+ outputType = args[3];
66
+
67
+ if (kek.length !== 16 && kek.length !== 24 && kek.length !== 32) {
68
+ throw new OperationError("KEK must be either 16, 24, or 32 bytes (currently " + kek.length + " bytes)");
69
+ }
70
+ if (iv.length !== 8) {
71
+ throw new OperationError("IV must be 8 bytes (currently " + iv.length + " bytes)");
72
+ }
73
+ const inputData = Utils.convertToByteString(input, inputType);
74
+ if (inputData.length % 8 !== 0 || inputData.length < 24) {
75
+ throw new OperationError("input must be 8n (n>=3) bytes (currently " + inputData.length + " bytes)");
76
+ }
77
+
78
+ const cipher = forge.cipher.createCipher("AES-ECB", kek);
79
+ cipher.start();
80
+ cipher.update(forge.util.createBuffer(""));
81
+ cipher.finish();
82
+ const paddingBlock = cipher.output.getBytes();
83
+
84
+ const decipher = forge.cipher.createDecipher("AES-ECB", kek);
85
+
86
+ let A = inputData.substring(0, 8);
87
+ const R = [];
88
+ for (let i = 8; i < inputData.length; i += 8) {
89
+ R.push(inputData.substring(i, i + 8));
90
+ }
91
+ let cntLower = R.length >>> 0;
92
+ let cntUpper = (R.length / ((1 << 30) * 4)) >>> 0;
93
+ cntUpper = cntUpper * 6 + ((cntLower * 6 / ((1 << 30) * 4)) >>> 0);
94
+ cntLower = cntLower * 6 >>> 0;
95
+ for (let j = 5; j >= 0; j--) {
96
+ for (let i = R.length - 1; i >= 0; i--) {
97
+ const aBuffer = Utils.strToArrayBuffer(A);
98
+ const aView = new DataView(aBuffer);
99
+ aView.setUint32(0, aView.getUint32(0) ^ cntUpper);
100
+ aView.setUint32(4, aView.getUint32(4) ^ cntLower);
101
+ A = Utils.arrayBufferToStr(aBuffer, false);
102
+ decipher.start();
103
+ decipher.update(forge.util.createBuffer(A + R[i] + paddingBlock));
104
+ decipher.finish();
105
+ const B = decipher.output.getBytes();
106
+ A = B.substring(0, 8);
107
+ R[i] = B.substring(8, 16);
108
+ cntLower--;
109
+ if (cntLower < 0) {
110
+ cntUpper--;
111
+ cntLower = 0xffffffff;
112
+ }
113
+ }
114
+ }
115
+ if (A !== iv) {
116
+ throw new OperationError("IV mismatch");
117
+ }
118
+ const P = R.join("");
119
+
120
+ if (outputType === "Hex") {
121
+ return toHexFast(Utils.strToArrayBuffer(P));
122
+ }
123
+ return P;
124
+ }
125
+
126
+ }
127
+
128
+ export default AESKeyUnwrap;
@@ -0,0 +1,115 @@
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 { toHexFast } from "../lib/Hex.mjs";
10
+ import forge from "node-forge";
11
+ import OperationError from "../errors/OperationError.mjs";
12
+
13
+ /**
14
+ * AES Key Wrap operation
15
+ */
16
+ class AESKeyWrap extends Operation {
17
+
18
+ /**
19
+ * AESKeyWrap constructor
20
+ */
21
+ constructor() {
22
+ super();
23
+
24
+ this.name = "AES Key Wrap";
25
+ this.module = "Ciphers";
26
+ this.description = "A key wrapping algorithm defined in RFC3394, which is used to protect keys in untrusted storage or communications, using AES.<br><br>This algorithm uses an AES key (KEK: key-encryption key) and a 64-bit IV to encrypt 64-bit blocks.";
27
+ this.infoURL = "https://wikipedia.org/wiki/Key_wrap";
28
+ this.inputType = "string";
29
+ this.outputType = "string";
30
+ this.args = [
31
+ {
32
+ "name": "Key (KEK)",
33
+ "type": "toggleString",
34
+ "value": "",
35
+ "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
36
+ },
37
+ {
38
+ "name": "IV",
39
+ "type": "toggleString",
40
+ "value": "a6a6a6a6a6a6a6a6",
41
+ "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
42
+ },
43
+ {
44
+ "name": "Input",
45
+ "type": "option",
46
+ "value": ["Hex", "Raw"]
47
+ },
48
+ {
49
+ "name": "Output",
50
+ "type": "option",
51
+ "value": ["Hex", "Raw"]
52
+ },
53
+ ];
54
+ }
55
+
56
+ /**
57
+ * @param {string} input
58
+ * @param {Object[]} args
59
+ * @returns {string}
60
+ */
61
+ run(input, args) {
62
+ const kek = Utils.convertToByteString(args[0].string, args[0].option),
63
+ iv = Utils.convertToByteString(args[1].string, args[1].option),
64
+ inputType = args[2],
65
+ outputType = args[3];
66
+
67
+ if (kek.length !== 16 && kek.length !== 24 && kek.length !== 32) {
68
+ throw new OperationError("KEK must be either 16, 24, or 32 bytes (currently " + kek.length + " bytes)");
69
+ }
70
+ if (iv.length !== 8) {
71
+ throw new OperationError("IV must be 8 bytes (currently " + iv.length + " bytes)");
72
+ }
73
+ const inputData = Utils.convertToByteString(input, inputType);
74
+ if (inputData.length % 8 !== 0 || inputData.length < 16) {
75
+ throw new OperationError("input must be 8n (n>=2) bytes (currently " + inputData.length + " bytes)");
76
+ }
77
+
78
+ const cipher = forge.cipher.createCipher("AES-ECB", kek);
79
+
80
+ let A = iv;
81
+ const R = [];
82
+ for (let i = 0; i < inputData.length; i += 8) {
83
+ R.push(inputData.substring(i, i + 8));
84
+ }
85
+ let cntLower = 1, cntUpper = 0;
86
+ for (let j = 0; j < 6; j++) {
87
+ for (let i = 0; i < R.length; i++) {
88
+ cipher.start();
89
+ cipher.update(forge.util.createBuffer(A + R[i]));
90
+ cipher.finish();
91
+ const B = cipher.output.getBytes();
92
+ const msbBuffer = Utils.strToArrayBuffer(B.substring(0, 8));
93
+ const msbView = new DataView(msbBuffer);
94
+ msbView.setUint32(0, msbView.getUint32(0) ^ cntUpper);
95
+ msbView.setUint32(4, msbView.getUint32(4) ^ cntLower);
96
+ A = Utils.arrayBufferToStr(msbBuffer, false);
97
+ R[i] = B.substring(8, 16);
98
+ cntLower++;
99
+ if (cntLower > 0xffffffff) {
100
+ cntUpper++;
101
+ cntLower = 0;
102
+ }
103
+ }
104
+ }
105
+ const C = A + R.join("");
106
+
107
+ if (outputType === "Hex") {
108
+ return toHexFast(Utils.strToArrayBuffer(C));
109
+ }
110
+ return C;
111
+ }
112
+
113
+ }
114
+
115
+ export default AESKeyWrap;