cyberchef 9.40.0 → 9.43.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 +15 -0
- package/package.json +1 -1
- package/src/core/config/Categories.json +5 -0
- package/src/core/config/OperationConfig.json +140 -0
- package/src/core/config/modules/Ciphers.mjs +2 -0
- package/src/core/config/modules/Crypto.mjs +4 -0
- package/src/core/config/modules/Default.mjs +4 -0
- package/src/core/lib/LS47.mjs +244 -0
- package/src/core/operations/CaesarBoxCipher.mjs +61 -0
- package/src/core/operations/LS47Decrypt.mjs +57 -0
- package/src/core/operations/LS47Encrypt.mjs +62 -0
- package/src/core/operations/ROT13BruteForce.mjs +102 -0
- package/src/core/operations/ROT47BruteForce.mjs +82 -0
- package/src/core/operations/index.mjs +10 -0
- package/src/node/index.mjs +25 -0
- package/tests/operations/index.mjs +2 -0
- package/tests/operations/tests/CaesarBoxCipher.mjs +45 -0
- package/tests/operations/tests/LS47.mjs +45 -0
package/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,15 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
13
13
|
|
|
14
14
|
## Details
|
|
15
15
|
|
|
16
|
+
### [9.42.0] - 2022-07-08
|
|
17
|
+
- Added 'LS47 Encrypt' and 'LS47 Decrypt' operations [@n1073645] | [#951]
|
|
18
|
+
|
|
19
|
+
### [9.41.0] - 2022-07-08
|
|
20
|
+
- Added 'Caesar Box Cipher' operation [@n1073645] | [#1066]
|
|
21
|
+
|
|
22
|
+
### [9.40.0] - 2022-07-08
|
|
23
|
+
- Added 'P-list Viewer' operation [@n1073645] | [#906]
|
|
24
|
+
|
|
16
25
|
### [9.39.0] - 2022-06-09
|
|
17
26
|
- Added 'ELF Info' operation [@n1073645] | [#1364]
|
|
18
27
|
|
|
@@ -294,6 +303,9 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
294
303
|
|
|
295
304
|
|
|
296
305
|
|
|
306
|
+
[9.42.0]: https://github.com/gchq/CyberChef/releases/tag/v9.42.0
|
|
307
|
+
[9.41.0]: https://github.com/gchq/CyberChef/releases/tag/v9.41.0
|
|
308
|
+
[9.40.0]: https://github.com/gchq/CyberChef/releases/tag/v9.40.0
|
|
297
309
|
[9.39.0]: https://github.com/gchq/CyberChef/releases/tag/v9.39.0
|
|
298
310
|
[9.38.0]: https://github.com/gchq/CyberChef/releases/tag/v9.38.0
|
|
299
311
|
[9.37.0]: https://github.com/gchq/CyberChef/releases/tag/v9.37.0
|
|
@@ -491,10 +503,12 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
491
503
|
[#674]: https://github.com/gchq/CyberChef/pull/674
|
|
492
504
|
[#683]: https://github.com/gchq/CyberChef/pull/683
|
|
493
505
|
[#865]: https://github.com/gchq/CyberChef/pull/865
|
|
506
|
+
[#906]: https://github.com/gchq/CyberChef/pull/906
|
|
494
507
|
[#912]: https://github.com/gchq/CyberChef/pull/912
|
|
495
508
|
[#917]: https://github.com/gchq/CyberChef/pull/917
|
|
496
509
|
[#934]: https://github.com/gchq/CyberChef/pull/934
|
|
497
510
|
[#948]: https://github.com/gchq/CyberChef/pull/948
|
|
511
|
+
[#951]: https://github.com/gchq/CyberChef/pull/951
|
|
498
512
|
[#952]: https://github.com/gchq/CyberChef/pull/952
|
|
499
513
|
[#965]: https://github.com/gchq/CyberChef/pull/965
|
|
500
514
|
[#966]: https://github.com/gchq/CyberChef/pull/966
|
|
@@ -506,6 +520,7 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
506
520
|
[#1045]: https://github.com/gchq/CyberChef/pull/1045
|
|
507
521
|
[#1049]: https://github.com/gchq/CyberChef/pull/1049
|
|
508
522
|
[#1065]: https://github.com/gchq/CyberChef/pull/1065
|
|
523
|
+
[#1066]: https://github.com/gchq/CyberChef/pull/1066
|
|
509
524
|
[#1083]: https://github.com/gchq/CyberChef/pull/1083
|
|
510
525
|
[#1189]: https://github.com/gchq/CyberChef/pull/1189
|
|
511
526
|
[#1242]: https://github.com/gchq/CyberChef/pull/1242
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cyberchef",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.43.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",
|
|
@@ -79,6 +79,8 @@
|
|
|
79
79
|
"DES Decrypt",
|
|
80
80
|
"Triple DES Encrypt",
|
|
81
81
|
"Triple DES Decrypt",
|
|
82
|
+
"LS47 Encrypt",
|
|
83
|
+
"LS47 Decrypt",
|
|
82
84
|
"RC2 Encrypt",
|
|
83
85
|
"RC2 Decrypt",
|
|
84
86
|
"RC4",
|
|
@@ -86,7 +88,9 @@
|
|
|
86
88
|
"SM4 Encrypt",
|
|
87
89
|
"SM4 Decrypt",
|
|
88
90
|
"ROT13",
|
|
91
|
+
"ROT13 Brute Force",
|
|
89
92
|
"ROT47",
|
|
93
|
+
"ROT47 Brute Force",
|
|
90
94
|
"XOR",
|
|
91
95
|
"XOR Brute Force",
|
|
92
96
|
"Vigenère Encode",
|
|
@@ -97,6 +101,7 @@
|
|
|
97
101
|
"Bacon Cipher Decode",
|
|
98
102
|
"Bifid Cipher Encode",
|
|
99
103
|
"Bifid Cipher Decode",
|
|
104
|
+
"Caesar Box Cipher",
|
|
100
105
|
"Affine Cipher Encode",
|
|
101
106
|
"Affine Cipher Decode",
|
|
102
107
|
"A1Z26 Cipher Encode",
|
|
@@ -1469,6 +1469,22 @@
|
|
|
1469
1469
|
"manualBake": false,
|
|
1470
1470
|
"args": []
|
|
1471
1471
|
},
|
|
1472
|
+
"Caesar Box Cipher": {
|
|
1473
|
+
"module": "Ciphers",
|
|
1474
|
+
"description": "Caesar Box is a transposition cipher used in the Roman Empire, in which letters of the message are written in rows in a square (or a rectangle) and then, read by column.",
|
|
1475
|
+
"infoURL": "https://www.dcode.fr/caesar-box-cipher",
|
|
1476
|
+
"inputType": "string",
|
|
1477
|
+
"outputType": "string",
|
|
1478
|
+
"flowControl": false,
|
|
1479
|
+
"manualBake": false,
|
|
1480
|
+
"args": [
|
|
1481
|
+
{
|
|
1482
|
+
"name": "Box Height",
|
|
1483
|
+
"type": "number",
|
|
1484
|
+
"value": 1
|
|
1485
|
+
}
|
|
1486
|
+
]
|
|
1487
|
+
},
|
|
1472
1488
|
"Cartesian Product": {
|
|
1473
1489
|
"module": "Default",
|
|
1474
1490
|
"description": "Calculates the cartesian product of multiple sets of data, returning all possible combinations.",
|
|
@@ -7918,6 +7934,53 @@
|
|
|
7918
7934
|
}
|
|
7919
7935
|
]
|
|
7920
7936
|
},
|
|
7937
|
+
"LS47 Decrypt": {
|
|
7938
|
+
"module": "Crypto",
|
|
7939
|
+
"description": "This is a slight improvement of the ElsieFour cipher as described by Alan Kaminsky. We use 7x7 characters instead of original (barely fitting) 6x6, to be able to encrypt some structured information. We also describe a simple key-expansion algorithm, because remembering passwords is popular. Similar security considerations as with ElsieFour hold.<br>The LS47 alphabet consists of following characters: <code>_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()</code><br>An LS47 key is a permutation of the alphabet that is then represented in a 7x7 grid used for the encryption or decryption.",
|
|
7940
|
+
"infoURL": "https://github.com/exaexa/ls47",
|
|
7941
|
+
"inputType": "string",
|
|
7942
|
+
"outputType": "string",
|
|
7943
|
+
"flowControl": false,
|
|
7944
|
+
"manualBake": false,
|
|
7945
|
+
"args": [
|
|
7946
|
+
{
|
|
7947
|
+
"name": "Password",
|
|
7948
|
+
"type": "string",
|
|
7949
|
+
"value": ""
|
|
7950
|
+
},
|
|
7951
|
+
{
|
|
7952
|
+
"name": "Padding",
|
|
7953
|
+
"type": "number",
|
|
7954
|
+
"value": 10
|
|
7955
|
+
}
|
|
7956
|
+
]
|
|
7957
|
+
},
|
|
7958
|
+
"LS47 Encrypt": {
|
|
7959
|
+
"module": "Crypto",
|
|
7960
|
+
"description": "This is a slight improvement of the ElsieFour cipher as described by Alan Kaminsky. We use 7x7 characters instead of original (barely fitting) 6x6, to be able to encrypt some structured information. We also describe a simple key-expansion algorithm, because remembering passwords is popular. Similar security considerations as with ElsieFour hold.<br>The LS47 alphabet consists of following characters: <code>_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()</code><br>A LS47 key is a permutation of the alphabet that is then represented in a 7x7 grid used for the encryption or decryption.",
|
|
7961
|
+
"infoURL": "https://github.com/exaexa/ls47",
|
|
7962
|
+
"inputType": "string",
|
|
7963
|
+
"outputType": "string",
|
|
7964
|
+
"flowControl": false,
|
|
7965
|
+
"manualBake": false,
|
|
7966
|
+
"args": [
|
|
7967
|
+
{
|
|
7968
|
+
"name": "Password",
|
|
7969
|
+
"type": "string",
|
|
7970
|
+
"value": ""
|
|
7971
|
+
},
|
|
7972
|
+
{
|
|
7973
|
+
"name": "Padding",
|
|
7974
|
+
"type": "number",
|
|
7975
|
+
"value": 10
|
|
7976
|
+
},
|
|
7977
|
+
{
|
|
7978
|
+
"name": "Signature",
|
|
7979
|
+
"type": "string",
|
|
7980
|
+
"value": ""
|
|
7981
|
+
}
|
|
7982
|
+
]
|
|
7983
|
+
},
|
|
7921
7984
|
"Label": {
|
|
7922
7985
|
"module": "Default",
|
|
7923
7986
|
"description": "Provides a location for conditional and fixed jumps to redirect execution to.",
|
|
@@ -10115,6 +10178,52 @@
|
|
|
10115
10178
|
}
|
|
10116
10179
|
]
|
|
10117
10180
|
},
|
|
10181
|
+
"ROT13 Brute Force": {
|
|
10182
|
+
"module": "Default",
|
|
10183
|
+
"description": "Try all meaningful amounts for ROT13.<br><br>Optionally you can enter your known plaintext (crib) to filter the result.",
|
|
10184
|
+
"infoURL": "https://wikipedia.org/wiki/ROT13",
|
|
10185
|
+
"inputType": "byteArray",
|
|
10186
|
+
"outputType": "string",
|
|
10187
|
+
"flowControl": false,
|
|
10188
|
+
"manualBake": false,
|
|
10189
|
+
"args": [
|
|
10190
|
+
{
|
|
10191
|
+
"name": "Rotate lower case chars",
|
|
10192
|
+
"type": "boolean",
|
|
10193
|
+
"value": true
|
|
10194
|
+
},
|
|
10195
|
+
{
|
|
10196
|
+
"name": "Rotate upper case chars",
|
|
10197
|
+
"type": "boolean",
|
|
10198
|
+
"value": true
|
|
10199
|
+
},
|
|
10200
|
+
{
|
|
10201
|
+
"name": "Rotate numbers",
|
|
10202
|
+
"type": "boolean",
|
|
10203
|
+
"value": false
|
|
10204
|
+
},
|
|
10205
|
+
{
|
|
10206
|
+
"name": "Sample length",
|
|
10207
|
+
"type": "number",
|
|
10208
|
+
"value": 100
|
|
10209
|
+
},
|
|
10210
|
+
{
|
|
10211
|
+
"name": "Sample offset",
|
|
10212
|
+
"type": "number",
|
|
10213
|
+
"value": 0
|
|
10214
|
+
},
|
|
10215
|
+
{
|
|
10216
|
+
"name": "Print amount",
|
|
10217
|
+
"type": "boolean",
|
|
10218
|
+
"value": true
|
|
10219
|
+
},
|
|
10220
|
+
{
|
|
10221
|
+
"name": "Crib (known plaintext string)",
|
|
10222
|
+
"type": "string",
|
|
10223
|
+
"value": ""
|
|
10224
|
+
}
|
|
10225
|
+
]
|
|
10226
|
+
},
|
|
10118
10227
|
"ROT47": {
|
|
10119
10228
|
"module": "Default",
|
|
10120
10229
|
"description": "A slightly more complex variation of a caesar cipher, which includes ASCII characters from 33 '!' to 126 '~'. Default rotation: 47.",
|
|
@@ -10131,6 +10240,37 @@
|
|
|
10131
10240
|
}
|
|
10132
10241
|
]
|
|
10133
10242
|
},
|
|
10243
|
+
"ROT47 Brute Force": {
|
|
10244
|
+
"module": "Default",
|
|
10245
|
+
"description": "Try all meaningful amounts for ROT47.<br><br>Optionally you can enter your known plaintext (crib) to filter the result.",
|
|
10246
|
+
"infoURL": "https://wikipedia.org/wiki/ROT13#Variants",
|
|
10247
|
+
"inputType": "byteArray",
|
|
10248
|
+
"outputType": "string",
|
|
10249
|
+
"flowControl": false,
|
|
10250
|
+
"manualBake": false,
|
|
10251
|
+
"args": [
|
|
10252
|
+
{
|
|
10253
|
+
"name": "Sample length",
|
|
10254
|
+
"type": "number",
|
|
10255
|
+
"value": 100
|
|
10256
|
+
},
|
|
10257
|
+
{
|
|
10258
|
+
"name": "Sample offset",
|
|
10259
|
+
"type": "number",
|
|
10260
|
+
"value": 0
|
|
10261
|
+
},
|
|
10262
|
+
{
|
|
10263
|
+
"name": "Print amount",
|
|
10264
|
+
"type": "boolean",
|
|
10265
|
+
"value": true
|
|
10266
|
+
},
|
|
10267
|
+
{
|
|
10268
|
+
"name": "Crib (known plaintext string)",
|
|
10269
|
+
"type": "string",
|
|
10270
|
+
"value": ""
|
|
10271
|
+
}
|
|
10272
|
+
]
|
|
10273
|
+
},
|
|
10134
10274
|
"RSA Decrypt": {
|
|
10135
10275
|
"module": "Ciphers",
|
|
10136
10276
|
"description": "Decrypt an RSA encrypted message with a PEM encoded private key.",
|
|
@@ -16,6 +16,7 @@ import BifidCipherDecode from "../../operations/BifidCipherDecode.mjs";
|
|
|
16
16
|
import BifidCipherEncode from "../../operations/BifidCipherEncode.mjs";
|
|
17
17
|
import BlowfishDecrypt from "../../operations/BlowfishDecrypt.mjs";
|
|
18
18
|
import BlowfishEncrypt from "../../operations/BlowfishEncrypt.mjs";
|
|
19
|
+
import CaesarBoxCipher from "../../operations/CaesarBoxCipher.mjs";
|
|
19
20
|
import DESDecrypt from "../../operations/DESDecrypt.mjs";
|
|
20
21
|
import DESEncrypt from "../../operations/DESEncrypt.mjs";
|
|
21
22
|
import DeriveEVPKey from "../../operations/DeriveEVPKey.mjs";
|
|
@@ -53,6 +54,7 @@ OpModules.Ciphers = {
|
|
|
53
54
|
"Bifid Cipher Encode": BifidCipherEncode,
|
|
54
55
|
"Blowfish Decrypt": BlowfishDecrypt,
|
|
55
56
|
"Blowfish Encrypt": BlowfishEncrypt,
|
|
57
|
+
"Caesar Box Cipher": CaesarBoxCipher,
|
|
56
58
|
"DES Decrypt": DESDecrypt,
|
|
57
59
|
"DES Encrypt": DESEncrypt,
|
|
58
60
|
"Derive EVP key": DeriveEVPKey,
|
|
@@ -34,6 +34,8 @@ import JWTDecode from "../../operations/JWTDecode.mjs";
|
|
|
34
34
|
import JWTSign from "../../operations/JWTSign.mjs";
|
|
35
35
|
import JWTVerify from "../../operations/JWTVerify.mjs";
|
|
36
36
|
import Keccak from "../../operations/Keccak.mjs";
|
|
37
|
+
import LS47Decrypt from "../../operations/LS47Decrypt.mjs";
|
|
38
|
+
import LS47Encrypt from "../../operations/LS47Encrypt.mjs";
|
|
37
39
|
import MD2 from "../../operations/MD2.mjs";
|
|
38
40
|
import MD4 from "../../operations/MD4.mjs";
|
|
39
41
|
import MD5 from "../../operations/MD5.mjs";
|
|
@@ -83,6 +85,8 @@ OpModules.Crypto = {
|
|
|
83
85
|
"JWT Sign": JWTSign,
|
|
84
86
|
"JWT Verify": JWTVerify,
|
|
85
87
|
"Keccak": Keccak,
|
|
88
|
+
"LS47 Decrypt": LS47Decrypt,
|
|
89
|
+
"LS47 Encrypt": LS47Encrypt,
|
|
86
90
|
"MD2": MD2,
|
|
87
91
|
"MD4": MD4,
|
|
88
92
|
"MD5": MD5,
|
|
@@ -107,7 +107,9 @@ import ParseUNIXFilePermissions from "../../operations/ParseUNIXFilePermissions.
|
|
|
107
107
|
import PlayMedia from "../../operations/PlayMedia.mjs";
|
|
108
108
|
import PowerSet from "../../operations/PowerSet.mjs";
|
|
109
109
|
import ROT13 from "../../operations/ROT13.mjs";
|
|
110
|
+
import ROT13BruteForce from "../../operations/ROT13BruteForce.mjs";
|
|
110
111
|
import ROT47 from "../../operations/ROT47.mjs";
|
|
112
|
+
import ROT47BruteForce from "../../operations/ROT47BruteForce.mjs";
|
|
111
113
|
import RemoveDiacritics from "../../operations/RemoveDiacritics.mjs";
|
|
112
114
|
import RemoveLineNumbers from "../../operations/RemoveLineNumbers.mjs";
|
|
113
115
|
import RemoveNullBytes from "../../operations/RemoveNullBytes.mjs";
|
|
@@ -277,7 +279,9 @@ OpModules.Default = {
|
|
|
277
279
|
"Play Media": PlayMedia,
|
|
278
280
|
"Power Set": PowerSet,
|
|
279
281
|
"ROT13": ROT13,
|
|
282
|
+
"ROT13 Brute Force": ROT13BruteForce,
|
|
280
283
|
"ROT47": ROT47,
|
|
284
|
+
"ROT47 Brute Force": ROT47BruteForce,
|
|
281
285
|
"Remove Diacritics": RemoveDiacritics,
|
|
282
286
|
"Remove line numbers": RemoveLineNumbers,
|
|
283
287
|
"Remove null bytes": RemoveNullBytes,
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author n1073645 [n1073645@gmail.com]
|
|
3
|
+
* @copyright Crown Copyright 2020
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import OperationError from "../errors/OperationError.mjs";
|
|
8
|
+
|
|
9
|
+
const letters = "_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()";
|
|
10
|
+
const tiles = [];
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Initialises the tiles with values and positions.
|
|
14
|
+
*/
|
|
15
|
+
export function initTiles() {
|
|
16
|
+
for (let i = 0; i < 49; i++)
|
|
17
|
+
tiles.push([letters.charAt(i), [Math.floor(i/7), i % 7]]);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Rotates the key "down".
|
|
22
|
+
*
|
|
23
|
+
* @param {string} key
|
|
24
|
+
* @param {number} col
|
|
25
|
+
* @param {number} n
|
|
26
|
+
* @returns {string}
|
|
27
|
+
*/
|
|
28
|
+
function rotateDown(key, col, n) {
|
|
29
|
+
const lines = [];
|
|
30
|
+
for (let i = 0; i < 7; i++)
|
|
31
|
+
lines.push(key.slice(i*7, (i + 1) * 7));
|
|
32
|
+
const lefts = [];
|
|
33
|
+
let mids = [];
|
|
34
|
+
const rights = [];
|
|
35
|
+
lines.forEach((element) => {
|
|
36
|
+
lefts.push(element.slice(0, col));
|
|
37
|
+
mids.push(element.charAt(col));
|
|
38
|
+
rights.push(element.slice(col+1));
|
|
39
|
+
});
|
|
40
|
+
n = (7 - n % 7) % 7;
|
|
41
|
+
mids = mids.slice(n).concat(mids.slice(0, n));
|
|
42
|
+
let result = "";
|
|
43
|
+
for (let i = 0; i < 7; i++)
|
|
44
|
+
result += lefts[i] + mids[i] + rights[i];
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Rotates the key "right".
|
|
50
|
+
*
|
|
51
|
+
* @param {string} key
|
|
52
|
+
* @param {number} row
|
|
53
|
+
* @param {number} n
|
|
54
|
+
* @returns {string}
|
|
55
|
+
*/
|
|
56
|
+
function rotateRight(key, row, n) {
|
|
57
|
+
const mid = key.slice(row * 7, (row + 1) * 7);
|
|
58
|
+
n = (7 - n % 7) % 7;
|
|
59
|
+
return key.slice(0, 7 * row) + mid.slice(n) + mid.slice(0, n) + key.slice(7 * (row + 1));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Finds the position of a letter in the tiles.
|
|
64
|
+
*
|
|
65
|
+
* @param {string} letter
|
|
66
|
+
* @returns {string}
|
|
67
|
+
*/
|
|
68
|
+
function findIx(letter) {
|
|
69
|
+
for (let i = 0; i < tiles.length; i++)
|
|
70
|
+
if (tiles[i][0] === letter)
|
|
71
|
+
return tiles[i][1];
|
|
72
|
+
throw new OperationError("Letter " + letter + " is not included in LS47");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Derives key from the input password.
|
|
77
|
+
*
|
|
78
|
+
* @param {string} password
|
|
79
|
+
* @returns {string}
|
|
80
|
+
*/
|
|
81
|
+
export function deriveKey(password) {
|
|
82
|
+
let i = 0;
|
|
83
|
+
let k = letters;
|
|
84
|
+
for (const c of password) {
|
|
85
|
+
const [row, col] = findIx(c);
|
|
86
|
+
k = rotateDown(rotateRight(k, i, col), i, row);
|
|
87
|
+
i = (i + 1) % 7;
|
|
88
|
+
}
|
|
89
|
+
return k;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Checks the key is a valid key.
|
|
94
|
+
*
|
|
95
|
+
* @param {string} key
|
|
96
|
+
*/
|
|
97
|
+
function checkKey(key) {
|
|
98
|
+
if (key.length !== letters.length)
|
|
99
|
+
throw new OperationError("Wrong key size");
|
|
100
|
+
const counts = new Array();
|
|
101
|
+
for (let i = 0; i < letters.length; i++)
|
|
102
|
+
counts[letters.charAt(i)] = 0;
|
|
103
|
+
for (const elem of letters) {
|
|
104
|
+
if (letters.indexOf(elem) === -1)
|
|
105
|
+
throw new OperationError("Letter " + elem + " not in LS47");
|
|
106
|
+
counts[elem]++;
|
|
107
|
+
if (counts[elem] > 1)
|
|
108
|
+
throw new OperationError("Letter duplicated in the key");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Finds the position of a letter in they key.
|
|
114
|
+
*
|
|
115
|
+
* @param {letter} key
|
|
116
|
+
* @param {string} letter
|
|
117
|
+
* @returns {object}
|
|
118
|
+
*/
|
|
119
|
+
function findPos (key, letter) {
|
|
120
|
+
const index = key.indexOf(letter);
|
|
121
|
+
if (index >= 0 && index < 49)
|
|
122
|
+
return [Math.floor(index/7), index%7];
|
|
123
|
+
throw new OperationError("Letter " + letter + " is not in the key");
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Returns the character at the position on the tiles.
|
|
128
|
+
*
|
|
129
|
+
* @param {string} key
|
|
130
|
+
* @param {object} coord
|
|
131
|
+
* @returns {string}
|
|
132
|
+
*/
|
|
133
|
+
function findAtPos(key, coord) {
|
|
134
|
+
return key.charAt(coord[1] + (coord[0] * 7));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Returns new position by adding two positions.
|
|
139
|
+
*
|
|
140
|
+
* @param {object} a
|
|
141
|
+
* @param {object} b
|
|
142
|
+
* @returns {object}
|
|
143
|
+
*/
|
|
144
|
+
function addPos(a, b) {
|
|
145
|
+
return [(a[0] + b[0]) % 7, (a[1] + b[1]) % 7];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Returns new position by subtracting two positions.
|
|
150
|
+
* Note: We have to manually do the remainder division, since JS does not
|
|
151
|
+
* operate correctly on negative numbers (e.g. -3 % 4 = -3 when it should be 1).
|
|
152
|
+
*
|
|
153
|
+
* @param {object} a
|
|
154
|
+
* @param {object} b
|
|
155
|
+
* @returns {object}
|
|
156
|
+
*/
|
|
157
|
+
function subPos(a, b) {
|
|
158
|
+
const asub = a[0] - b[0];
|
|
159
|
+
const bsub = a[1] - b[1];
|
|
160
|
+
return [asub - (Math.floor(asub/7) * 7), bsub - (Math.floor(bsub/7) * 7)];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Encrypts the plaintext string.
|
|
165
|
+
*
|
|
166
|
+
* @param {string} key
|
|
167
|
+
* @param {string} plaintext
|
|
168
|
+
* @returns {string}
|
|
169
|
+
*/
|
|
170
|
+
function encrypt(key, plaintext) {
|
|
171
|
+
checkKey(key);
|
|
172
|
+
let mp = [0, 0];
|
|
173
|
+
let ciphertext = "";
|
|
174
|
+
for (const p of plaintext) {
|
|
175
|
+
const pp = findPos(key, p);
|
|
176
|
+
const mix = findIx(findAtPos(key, mp));
|
|
177
|
+
let cp = addPos(pp, mix);
|
|
178
|
+
const c = findAtPos(key, cp);
|
|
179
|
+
ciphertext += c;
|
|
180
|
+
key = rotateRight(key, pp[0], 1);
|
|
181
|
+
cp = findPos(key, c);
|
|
182
|
+
key = rotateDown(key, cp[1], 1);
|
|
183
|
+
mp = addPos(mp, findIx(c));
|
|
184
|
+
}
|
|
185
|
+
return ciphertext;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Decrypts the ciphertext string.
|
|
190
|
+
*
|
|
191
|
+
* @param {string} key
|
|
192
|
+
* @param {string} ciphertext
|
|
193
|
+
* @returns {string}
|
|
194
|
+
*/
|
|
195
|
+
function decrypt(key, ciphertext) {
|
|
196
|
+
checkKey(key);
|
|
197
|
+
let mp = [0, 0];
|
|
198
|
+
let plaintext = "";
|
|
199
|
+
for (const c of ciphertext) {
|
|
200
|
+
let cp = findPos(key, c);
|
|
201
|
+
const mix = findIx(findAtPos(key, mp));
|
|
202
|
+
const pp = subPos(cp, mix);
|
|
203
|
+
const p = findAtPos(key, pp);
|
|
204
|
+
plaintext += p;
|
|
205
|
+
key = rotateRight(key, pp[0], 1);
|
|
206
|
+
cp = findPos(key, c);
|
|
207
|
+
key = rotateDown(key, cp[1], 1);
|
|
208
|
+
mp = addPos(mp, findIx(c));
|
|
209
|
+
}
|
|
210
|
+
return plaintext;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Adds padding to the input.
|
|
215
|
+
*
|
|
216
|
+
* @param {string} key
|
|
217
|
+
* @param {string} plaintext
|
|
218
|
+
* @param {string} signature
|
|
219
|
+
* @param {number} paddingSize
|
|
220
|
+
* @returns {string}
|
|
221
|
+
*/
|
|
222
|
+
export function encryptPad(key, plaintext, signature, paddingSize) {
|
|
223
|
+
initTiles();
|
|
224
|
+
checkKey(key);
|
|
225
|
+
let padding = "";
|
|
226
|
+
for (let i = 0; i < paddingSize; i++) {
|
|
227
|
+
padding += letters.charAt(Math.floor(Math.random() * letters.length));
|
|
228
|
+
}
|
|
229
|
+
return encrypt(key, padding+plaintext+"---"+signature);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Removes padding from the ouput.
|
|
234
|
+
*
|
|
235
|
+
* @param {string} key
|
|
236
|
+
* @param {string} ciphertext
|
|
237
|
+
* @param {number} paddingSize
|
|
238
|
+
* @returns {string}
|
|
239
|
+
*/
|
|
240
|
+
export function decryptPad(key, ciphertext, paddingSize) {
|
|
241
|
+
initTiles();
|
|
242
|
+
checkKey(key);
|
|
243
|
+
return decrypt(key, ciphertext).slice(paddingSize);
|
|
244
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author n1073645 [n1073645@gmail.com]
|
|
3
|
+
* @copyright Crown Copyright 2020
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Operation from "../Operation.mjs";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Caesar Box Cipher operation
|
|
11
|
+
*/
|
|
12
|
+
class CaesarBoxCipher extends Operation {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* CaesarBoxCipher constructor
|
|
16
|
+
*/
|
|
17
|
+
constructor() {
|
|
18
|
+
super();
|
|
19
|
+
|
|
20
|
+
this.name = "Caesar Box Cipher";
|
|
21
|
+
this.module = "Ciphers";
|
|
22
|
+
this.description = "Caesar Box is a transposition cipher used in the Roman Empire, in which letters of the message are written in rows in a square (or a rectangle) and then, read by column.";
|
|
23
|
+
this.infoURL = "https://www.dcode.fr/caesar-box-cipher";
|
|
24
|
+
this.inputType = "string";
|
|
25
|
+
this.outputType = "string";
|
|
26
|
+
this.args = [
|
|
27
|
+
{
|
|
28
|
+
name: "Box Height",
|
|
29
|
+
type: "number",
|
|
30
|
+
value: 1
|
|
31
|
+
}
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @param {string} input
|
|
37
|
+
* @param {Object[]} args
|
|
38
|
+
* @returns {string}
|
|
39
|
+
*/
|
|
40
|
+
run(input, args) {
|
|
41
|
+
const tableHeight = args[0];
|
|
42
|
+
const tableWidth = Math.ceil(input.length / tableHeight);
|
|
43
|
+
while (input.indexOf(" ") !== -1)
|
|
44
|
+
input = input.replace(" ", "");
|
|
45
|
+
for (let i = 0; i < (tableHeight * tableWidth) - input.length; i++) {
|
|
46
|
+
input += "\x00";
|
|
47
|
+
}
|
|
48
|
+
let result = "";
|
|
49
|
+
for (let i = 0; i < tableHeight; i++) {
|
|
50
|
+
for (let j = i; j < input.length; j += tableHeight) {
|
|
51
|
+
if (input.charAt(j) !== "\x00") {
|
|
52
|
+
result += input.charAt(j);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default CaesarBoxCipher;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author n1073645 [n1073645@gmail.com]
|
|
3
|
+
* @copyright Crown Copyright 2020
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Operation from "../Operation.mjs";
|
|
8
|
+
import * as LS47 from "../lib/LS47.mjs";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* LS47 Decrypt operation
|
|
12
|
+
*/
|
|
13
|
+
class LS47Decrypt extends Operation {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* LS47Decrypt constructor
|
|
17
|
+
*/
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
|
|
21
|
+
this.name = "LS47 Decrypt";
|
|
22
|
+
this.module = "Crypto";
|
|
23
|
+
this.description = "This is a slight improvement of the ElsieFour cipher as described by Alan Kaminsky. We use 7x7 characters instead of original (barely fitting) 6x6, to be able to encrypt some structured information. We also describe a simple key-expansion algorithm, because remembering passwords is popular. Similar security considerations as with ElsieFour hold.<br>The LS47 alphabet consists of following characters: <code>_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()</code><br>An LS47 key is a permutation of the alphabet that is then represented in a 7x7 grid used for the encryption or decryption.";
|
|
24
|
+
this.infoURL = "https://github.com/exaexa/ls47";
|
|
25
|
+
this.inputType = "string";
|
|
26
|
+
this.outputType = "string";
|
|
27
|
+
this.args = [
|
|
28
|
+
{
|
|
29
|
+
name: "Password",
|
|
30
|
+
type: "string",
|
|
31
|
+
value: ""
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "Padding",
|
|
35
|
+
type: "number",
|
|
36
|
+
value: 10
|
|
37
|
+
}
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {string} input
|
|
43
|
+
* @param {Object[]} args
|
|
44
|
+
* @returns {string}
|
|
45
|
+
*/
|
|
46
|
+
run(input, args) {
|
|
47
|
+
this.paddingSize = parseInt(args[1], 10);
|
|
48
|
+
|
|
49
|
+
LS47.initTiles();
|
|
50
|
+
|
|
51
|
+
const key = LS47.deriveKey(args[0]);
|
|
52
|
+
return LS47.decryptPad(key, input, this.paddingSize);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default LS47Decrypt;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author n1073645 [n1073645@gmail.com]
|
|
3
|
+
* @copyright Crown Copyright 2020
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Operation from "../Operation.mjs";
|
|
8
|
+
import * as LS47 from "../lib/LS47.mjs";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* LS47 Encrypt operation
|
|
12
|
+
*/
|
|
13
|
+
class LS47Encrypt extends Operation {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* LS47Encrypt constructor
|
|
17
|
+
*/
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
|
|
21
|
+
this.name = "LS47 Encrypt";
|
|
22
|
+
this.module = "Crypto";
|
|
23
|
+
this.description = "This is a slight improvement of the ElsieFour cipher as described by Alan Kaminsky. We use 7x7 characters instead of original (barely fitting) 6x6, to be able to encrypt some structured information. We also describe a simple key-expansion algorithm, because remembering passwords is popular. Similar security considerations as with ElsieFour hold.<br>The LS47 alphabet consists of following characters: <code>_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()</code><br>A LS47 key is a permutation of the alphabet that is then represented in a 7x7 grid used for the encryption or decryption.";
|
|
24
|
+
this.infoURL = "https://github.com/exaexa/ls47";
|
|
25
|
+
this.inputType = "string";
|
|
26
|
+
this.outputType = "string";
|
|
27
|
+
this.args = [
|
|
28
|
+
{
|
|
29
|
+
name: "Password",
|
|
30
|
+
type: "string",
|
|
31
|
+
value: ""
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "Padding",
|
|
35
|
+
type: "number",
|
|
36
|
+
value: 10
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "Signature",
|
|
40
|
+
type: "string",
|
|
41
|
+
value: ""
|
|
42
|
+
}
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @param {string} input
|
|
48
|
+
* @param {Object[]} args
|
|
49
|
+
* @returns {string}
|
|
50
|
+
*/
|
|
51
|
+
run(input, args) {
|
|
52
|
+
this.paddingSize = parseInt(args[1], 10);
|
|
53
|
+
|
|
54
|
+
LS47.initTiles();
|
|
55
|
+
|
|
56
|
+
const key = LS47.deriveKey(args[0]);
|
|
57
|
+
return LS47.encryptPad(key, input, args[2], this.paddingSize);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default LS47Encrypt;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author MikeCAT
|
|
3
|
+
* @license Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import Operation from "../Operation.mjs";
|
|
7
|
+
import Utils from "../Utils.mjs";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* ROT13 Brute Force operation.
|
|
11
|
+
*/
|
|
12
|
+
class ROT13BruteForce extends Operation {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* ROT13BruteForce constructor
|
|
16
|
+
*/
|
|
17
|
+
constructor() {
|
|
18
|
+
super();
|
|
19
|
+
|
|
20
|
+
this.name = "ROT13 Brute Force";
|
|
21
|
+
this.module = "Default";
|
|
22
|
+
this.description = "Try all meaningful amounts for ROT13.<br><br>Optionally you can enter your known plaintext (crib) to filter the result.";
|
|
23
|
+
this.infoURL = "https://wikipedia.org/wiki/ROT13";
|
|
24
|
+
this.inputType = "byteArray";
|
|
25
|
+
this.outputType = "string";
|
|
26
|
+
this.args = [
|
|
27
|
+
{
|
|
28
|
+
name: "Rotate lower case chars",
|
|
29
|
+
type: "boolean",
|
|
30
|
+
value: true
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "Rotate upper case chars",
|
|
34
|
+
type: "boolean",
|
|
35
|
+
value: true
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "Rotate numbers",
|
|
39
|
+
type: "boolean",
|
|
40
|
+
value: false
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "Sample length",
|
|
44
|
+
type: "number",
|
|
45
|
+
value: 100
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: "Sample offset",
|
|
49
|
+
type: "number",
|
|
50
|
+
value: 0
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "Print amount",
|
|
54
|
+
type: "boolean",
|
|
55
|
+
value: true
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: "Crib (known plaintext string)",
|
|
59
|
+
type: "string",
|
|
60
|
+
value: ""
|
|
61
|
+
}
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @param {byteArray} input
|
|
67
|
+
* @param {Object[]} args
|
|
68
|
+
* @returns {string}
|
|
69
|
+
*/
|
|
70
|
+
run(input, args) {
|
|
71
|
+
const [rotateLower, rotateUpper, rotateNum, sampleLength, sampleOffset, printAmount, crib] = args;
|
|
72
|
+
const sample = input.slice(sampleOffset, sampleOffset + sampleLength);
|
|
73
|
+
const cribLower = crib.toLowerCase();
|
|
74
|
+
const lowerStart = "a".charCodeAt(0), upperStart = "A".charCodeAt(0), numStart = "0".charCodeAt(0);
|
|
75
|
+
const result = [];
|
|
76
|
+
for (let amount = 1; amount < 26; amount++) {
|
|
77
|
+
const rotated = sample.slice();
|
|
78
|
+
for (let i = 0; i < rotated.length; i++) {
|
|
79
|
+
if (rotateLower && lowerStart <= rotated[i] && rotated[i] < lowerStart + 26) {
|
|
80
|
+
rotated[i] = (rotated[i] - lowerStart + amount) % 26 + lowerStart;
|
|
81
|
+
} else if (rotateUpper && upperStart <= rotated[i] && rotated[i] < upperStart + 26) {
|
|
82
|
+
rotated[i] = (rotated[i] - upperStart + amount) % 26 + upperStart;
|
|
83
|
+
} else if (rotateNum && numStart <= rotated[i] && rotated[i] < numStart + 10) {
|
|
84
|
+
rotated[i] = (rotated[i] - numStart + amount) % 10 + numStart;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const rotatedString = Utils.byteArrayToUtf8(rotated);
|
|
88
|
+
if (rotatedString.toLowerCase().indexOf(cribLower) >= 0) {
|
|
89
|
+
const rotatedStringPrintable = Utils.printable(rotatedString, false);
|
|
90
|
+
if (printAmount) {
|
|
91
|
+
const amountStr = "Amount = " + (" " + amount).slice(-2) + ": ";
|
|
92
|
+
result.push(amountStr + rotatedStringPrintable);
|
|
93
|
+
} else {
|
|
94
|
+
result.push(rotatedStringPrintable);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return result.join("\n");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export default ROT13BruteForce;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author MikeCAT
|
|
3
|
+
* @license Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import Operation from "../Operation.mjs";
|
|
7
|
+
import Utils from "../Utils.mjs";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* ROT47 Brute Force operation.
|
|
11
|
+
*/
|
|
12
|
+
class ROT47BruteForce extends Operation {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* ROT47BruteForce constructor
|
|
16
|
+
*/
|
|
17
|
+
constructor() {
|
|
18
|
+
super();
|
|
19
|
+
|
|
20
|
+
this.name = "ROT47 Brute Force";
|
|
21
|
+
this.module = "Default";
|
|
22
|
+
this.description = "Try all meaningful amounts for ROT47.<br><br>Optionally you can enter your known plaintext (crib) to filter the result.";
|
|
23
|
+
this.infoURL = "https://wikipedia.org/wiki/ROT13#Variants";
|
|
24
|
+
this.inputType = "byteArray";
|
|
25
|
+
this.outputType = "string";
|
|
26
|
+
this.args = [
|
|
27
|
+
{
|
|
28
|
+
name: "Sample length",
|
|
29
|
+
type: "number",
|
|
30
|
+
value: 100
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "Sample offset",
|
|
34
|
+
type: "number",
|
|
35
|
+
value: 0
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "Print amount",
|
|
39
|
+
type: "boolean",
|
|
40
|
+
value: true
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "Crib (known plaintext string)",
|
|
44
|
+
type: "string",
|
|
45
|
+
value: ""
|
|
46
|
+
}
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @param {byteArray} input
|
|
52
|
+
* @param {Object[]} args
|
|
53
|
+
* @returns {string}
|
|
54
|
+
*/
|
|
55
|
+
run(input, args) {
|
|
56
|
+
const [sampleLength, sampleOffset, printAmount, crib] = args;
|
|
57
|
+
const sample = input.slice(sampleOffset, sampleOffset + sampleLength);
|
|
58
|
+
const cribLower = crib.toLowerCase();
|
|
59
|
+
const result = [];
|
|
60
|
+
for (let amount = 1; amount < 94; amount++) {
|
|
61
|
+
const rotated = sample.slice();
|
|
62
|
+
for (let i = 0; i < rotated.length; i++) {
|
|
63
|
+
if (33 <= rotated[i] && rotated[i] <= 126) {
|
|
64
|
+
rotated[i] = (rotated[i] - 33 + amount) % 94 + 33;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const rotatedString = Utils.byteArrayToUtf8(rotated);
|
|
68
|
+
if (rotatedString.toLowerCase().indexOf(cribLower) >= 0) {
|
|
69
|
+
const rotatedStringPrintable = Utils.printable(rotatedString, false);
|
|
70
|
+
if (printAmount) {
|
|
71
|
+
const amountStr = "Amount = " + (" " + amount).slice(-2) + ": ";
|
|
72
|
+
result.push(amountStr + rotatedStringPrintable);
|
|
73
|
+
} else {
|
|
74
|
+
result.push(rotatedStringPrintable);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return result.join("\n");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export default ROT47BruteForce;
|
|
@@ -48,6 +48,7 @@ import CSSMinify from "./CSSMinify.mjs";
|
|
|
48
48
|
import CSSSelector from "./CSSSelector.mjs";
|
|
49
49
|
import CSVToJSON from "./CSVToJSON.mjs";
|
|
50
50
|
import CTPH from "./CTPH.mjs";
|
|
51
|
+
import CaesarBoxCipher from "./CaesarBoxCipher.mjs";
|
|
51
52
|
import CartesianProduct from "./CartesianProduct.mjs";
|
|
52
53
|
import ChangeIPFormat from "./ChangeIPFormat.mjs";
|
|
53
54
|
import ChiSquare from "./ChiSquare.mjs";
|
|
@@ -191,6 +192,8 @@ import JavaScriptMinify from "./JavaScriptMinify.mjs";
|
|
|
191
192
|
import JavaScriptParser from "./JavaScriptParser.mjs";
|
|
192
193
|
import Jump from "./Jump.mjs";
|
|
193
194
|
import Keccak from "./Keccak.mjs";
|
|
195
|
+
import LS47Decrypt from "./LS47Decrypt.mjs";
|
|
196
|
+
import LS47Encrypt from "./LS47Encrypt.mjs";
|
|
194
197
|
import Label from "./Label.mjs";
|
|
195
198
|
import Lorenz from "./Lorenz.mjs";
|
|
196
199
|
import LuhnChecksum from "./LuhnChecksum.mjs";
|
|
@@ -249,7 +252,9 @@ import RC4 from "./RC4.mjs";
|
|
|
249
252
|
import RC4Drop from "./RC4Drop.mjs";
|
|
250
253
|
import RIPEMD from "./RIPEMD.mjs";
|
|
251
254
|
import ROT13 from "./ROT13.mjs";
|
|
255
|
+
import ROT13BruteForce from "./ROT13BruteForce.mjs";
|
|
252
256
|
import ROT47 from "./ROT47.mjs";
|
|
257
|
+
import ROT47BruteForce from "./ROT47BruteForce.mjs";
|
|
253
258
|
import RSADecrypt from "./RSADecrypt.mjs";
|
|
254
259
|
import RSAEncrypt from "./RSAEncrypt.mjs";
|
|
255
260
|
import RSASign from "./RSASign.mjs";
|
|
@@ -423,6 +428,7 @@ export {
|
|
|
423
428
|
CSSSelector,
|
|
424
429
|
CSVToJSON,
|
|
425
430
|
CTPH,
|
|
431
|
+
CaesarBoxCipher,
|
|
426
432
|
CartesianProduct,
|
|
427
433
|
ChangeIPFormat,
|
|
428
434
|
ChiSquare,
|
|
@@ -566,6 +572,8 @@ export {
|
|
|
566
572
|
JavaScriptParser,
|
|
567
573
|
Jump,
|
|
568
574
|
Keccak,
|
|
575
|
+
LS47Decrypt,
|
|
576
|
+
LS47Encrypt,
|
|
569
577
|
Label,
|
|
570
578
|
Lorenz,
|
|
571
579
|
LuhnChecksum,
|
|
@@ -624,7 +632,9 @@ export {
|
|
|
624
632
|
RC4Drop,
|
|
625
633
|
RIPEMD,
|
|
626
634
|
ROT13,
|
|
635
|
+
ROT13BruteForce,
|
|
627
636
|
ROT47,
|
|
637
|
+
ROT47BruteForce,
|
|
628
638
|
RSADecrypt,
|
|
629
639
|
RSAEncrypt,
|
|
630
640
|
RSASign,
|
package/src/node/index.mjs
CHANGED
|
@@ -58,6 +58,7 @@ import {
|
|
|
58
58
|
CSSSelector as core_CSSSelector,
|
|
59
59
|
CSVToJSON as core_CSVToJSON,
|
|
60
60
|
CTPH as core_CTPH,
|
|
61
|
+
CaesarBoxCipher as core_CaesarBoxCipher,
|
|
61
62
|
CartesianProduct as core_CartesianProduct,
|
|
62
63
|
ChangeIPFormat as core_ChangeIPFormat,
|
|
63
64
|
ChiSquare as core_ChiSquare,
|
|
@@ -194,6 +195,8 @@ import {
|
|
|
194
195
|
JWTSign as core_JWTSign,
|
|
195
196
|
JWTVerify as core_JWTVerify,
|
|
196
197
|
Keccak as core_Keccak,
|
|
198
|
+
LS47Decrypt as core_LS47Decrypt,
|
|
199
|
+
LS47Encrypt as core_LS47Encrypt,
|
|
197
200
|
Lorenz as core_Lorenz,
|
|
198
201
|
LuhnChecksum as core_LuhnChecksum,
|
|
199
202
|
MD2 as core_MD2,
|
|
@@ -250,7 +253,9 @@ import {
|
|
|
250
253
|
RC4Drop as core_RC4Drop,
|
|
251
254
|
RIPEMD as core_RIPEMD,
|
|
252
255
|
ROT13 as core_ROT13,
|
|
256
|
+
ROT13BruteForce as core_ROT13BruteForce,
|
|
253
257
|
ROT47 as core_ROT47,
|
|
258
|
+
ROT47BruteForce as core_ROT47BruteForce,
|
|
254
259
|
RSADecrypt as core_RSADecrypt,
|
|
255
260
|
RSAEncrypt as core_RSAEncrypt,
|
|
256
261
|
RSASign as core_RSASign,
|
|
@@ -433,6 +438,7 @@ function generateChef() {
|
|
|
433
438
|
"CSSSelector": _wrap(core_CSSSelector),
|
|
434
439
|
"CSVToJSON": _wrap(core_CSVToJSON),
|
|
435
440
|
"CTPH": _wrap(core_CTPH),
|
|
441
|
+
"caesarBoxCipher": _wrap(core_CaesarBoxCipher),
|
|
436
442
|
"cartesianProduct": _wrap(core_CartesianProduct),
|
|
437
443
|
"changeIPFormat": _wrap(core_ChangeIPFormat),
|
|
438
444
|
"chiSquare": _wrap(core_ChiSquare),
|
|
@@ -569,6 +575,8 @@ function generateChef() {
|
|
|
569
575
|
"JWTSign": _wrap(core_JWTSign),
|
|
570
576
|
"JWTVerify": _wrap(core_JWTVerify),
|
|
571
577
|
"keccak": _wrap(core_Keccak),
|
|
578
|
+
"LS47Decrypt": _wrap(core_LS47Decrypt),
|
|
579
|
+
"LS47Encrypt": _wrap(core_LS47Encrypt),
|
|
572
580
|
"lorenz": _wrap(core_Lorenz),
|
|
573
581
|
"luhnChecksum": _wrap(core_LuhnChecksum),
|
|
574
582
|
"MD2": _wrap(core_MD2),
|
|
@@ -625,7 +633,9 @@ function generateChef() {
|
|
|
625
633
|
"RC4Drop": _wrap(core_RC4Drop),
|
|
626
634
|
"RIPEMD": _wrap(core_RIPEMD),
|
|
627
635
|
"ROT13": _wrap(core_ROT13),
|
|
636
|
+
"ROT13BruteForce": _wrap(core_ROT13BruteForce),
|
|
628
637
|
"ROT47": _wrap(core_ROT47),
|
|
638
|
+
"ROT47BruteForce": _wrap(core_ROT47BruteForce),
|
|
629
639
|
"RSADecrypt": _wrap(core_RSADecrypt),
|
|
630
640
|
"RSAEncrypt": _wrap(core_RSAEncrypt),
|
|
631
641
|
"RSASign": _wrap(core_RSASign),
|
|
@@ -816,6 +826,7 @@ const CSSMinify = chef.CSSMinify;
|
|
|
816
826
|
const CSSSelector = chef.CSSSelector;
|
|
817
827
|
const CSVToJSON = chef.CSVToJSON;
|
|
818
828
|
const CTPH = chef.CTPH;
|
|
829
|
+
const caesarBoxCipher = chef.caesarBoxCipher;
|
|
819
830
|
const cartesianProduct = chef.cartesianProduct;
|
|
820
831
|
const changeIPFormat = chef.changeIPFormat;
|
|
821
832
|
const chiSquare = chef.chiSquare;
|
|
@@ -959,6 +970,8 @@ const javaScriptMinify = chef.javaScriptMinify;
|
|
|
959
970
|
const javaScriptParser = chef.javaScriptParser;
|
|
960
971
|
const jump = chef.jump;
|
|
961
972
|
const keccak = chef.keccak;
|
|
973
|
+
const LS47Decrypt = chef.LS47Decrypt;
|
|
974
|
+
const LS47Encrypt = chef.LS47Encrypt;
|
|
962
975
|
const label = chef.label;
|
|
963
976
|
const lorenz = chef.lorenz;
|
|
964
977
|
const luhnChecksum = chef.luhnChecksum;
|
|
@@ -1017,7 +1030,9 @@ const RC4 = chef.RC4;
|
|
|
1017
1030
|
const RC4Drop = chef.RC4Drop;
|
|
1018
1031
|
const RIPEMD = chef.RIPEMD;
|
|
1019
1032
|
const ROT13 = chef.ROT13;
|
|
1033
|
+
const ROT13BruteForce = chef.ROT13BruteForce;
|
|
1020
1034
|
const ROT47 = chef.ROT47;
|
|
1035
|
+
const ROT47BruteForce = chef.ROT47BruteForce;
|
|
1021
1036
|
const RSADecrypt = chef.RSADecrypt;
|
|
1022
1037
|
const RSAEncrypt = chef.RSAEncrypt;
|
|
1023
1038
|
const RSASign = chef.RSASign;
|
|
@@ -1193,6 +1208,7 @@ const operations = [
|
|
|
1193
1208
|
CSSSelector,
|
|
1194
1209
|
CSVToJSON,
|
|
1195
1210
|
CTPH,
|
|
1211
|
+
caesarBoxCipher,
|
|
1196
1212
|
cartesianProduct,
|
|
1197
1213
|
changeIPFormat,
|
|
1198
1214
|
chiSquare,
|
|
@@ -1336,6 +1352,8 @@ const operations = [
|
|
|
1336
1352
|
javaScriptParser,
|
|
1337
1353
|
jump,
|
|
1338
1354
|
keccak,
|
|
1355
|
+
LS47Decrypt,
|
|
1356
|
+
LS47Encrypt,
|
|
1339
1357
|
label,
|
|
1340
1358
|
lorenz,
|
|
1341
1359
|
luhnChecksum,
|
|
@@ -1394,7 +1412,9 @@ const operations = [
|
|
|
1394
1412
|
RC4Drop,
|
|
1395
1413
|
RIPEMD,
|
|
1396
1414
|
ROT13,
|
|
1415
|
+
ROT13BruteForce,
|
|
1397
1416
|
ROT47,
|
|
1417
|
+
ROT47BruteForce,
|
|
1398
1418
|
RSADecrypt,
|
|
1399
1419
|
RSAEncrypt,
|
|
1400
1420
|
RSASign,
|
|
@@ -1574,6 +1594,7 @@ export {
|
|
|
1574
1594
|
CSSSelector,
|
|
1575
1595
|
CSVToJSON,
|
|
1576
1596
|
CTPH,
|
|
1597
|
+
caesarBoxCipher,
|
|
1577
1598
|
cartesianProduct,
|
|
1578
1599
|
changeIPFormat,
|
|
1579
1600
|
chiSquare,
|
|
@@ -1717,6 +1738,8 @@ export {
|
|
|
1717
1738
|
javaScriptParser,
|
|
1718
1739
|
jump,
|
|
1719
1740
|
keccak,
|
|
1741
|
+
LS47Decrypt,
|
|
1742
|
+
LS47Encrypt,
|
|
1720
1743
|
label,
|
|
1721
1744
|
lorenz,
|
|
1722
1745
|
luhnChecksum,
|
|
@@ -1775,7 +1798,9 @@ export {
|
|
|
1775
1798
|
RC4Drop,
|
|
1776
1799
|
RIPEMD,
|
|
1777
1800
|
ROT13,
|
|
1801
|
+
ROT13BruteForce,
|
|
1778
1802
|
ROT47,
|
|
1803
|
+
ROT47BruteForce,
|
|
1779
1804
|
RSADecrypt,
|
|
1780
1805
|
RSAEncrypt,
|
|
1781
1806
|
RSASign,
|
|
@@ -116,6 +116,8 @@ import "./tests/GetAllCasings.mjs";
|
|
|
116
116
|
import "./tests/SIGABA.mjs";
|
|
117
117
|
import "./tests/ELFInfo.mjs";
|
|
118
118
|
import "./tests/Subsection.mjs";
|
|
119
|
+
import "./tests/CaesarBoxCipher.mjs";
|
|
120
|
+
import "./tests/LS47.mjs";
|
|
119
121
|
|
|
120
122
|
|
|
121
123
|
// Cannot test operations that use the File type yet
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Caesar Box Cipher tests.
|
|
3
|
+
*
|
|
4
|
+
* @author n1073645 [n1073645@gmail.com]
|
|
5
|
+
*
|
|
6
|
+
* @copyright Crown Copyright 2020
|
|
7
|
+
* @license Apache-2.0
|
|
8
|
+
*/
|
|
9
|
+
import TestRegister from "../../lib/TestRegister.mjs";
|
|
10
|
+
|
|
11
|
+
TestRegister.addTests([
|
|
12
|
+
{
|
|
13
|
+
name: "Caesar Box Cipher: nothing",
|
|
14
|
+
input: "",
|
|
15
|
+
expectedOutput: "",
|
|
16
|
+
recipeConfig: [
|
|
17
|
+
{
|
|
18
|
+
op: "Caesar Box Cipher",
|
|
19
|
+
args: ["1"],
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: "Caesar Box Cipher: Hello World!",
|
|
25
|
+
input: "Hello World!",
|
|
26
|
+
expectedOutput: "Hlodeor!lWl",
|
|
27
|
+
recipeConfig: [
|
|
28
|
+
{
|
|
29
|
+
op: "Caesar Box Cipher",
|
|
30
|
+
args: ["3"],
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: "Caesar Box Cipher: Hello World!",
|
|
36
|
+
input: "Hlodeor!lWl",
|
|
37
|
+
expectedOutput: "HelloWorld!",
|
|
38
|
+
recipeConfig: [
|
|
39
|
+
{
|
|
40
|
+
op: "Caesar Box Cipher",
|
|
41
|
+
args: ["4"],
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
}
|
|
45
|
+
]);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LS47 tests.
|
|
3
|
+
*
|
|
4
|
+
* @author n1073645 [n1073645@gmail.com]
|
|
5
|
+
*
|
|
6
|
+
* @copyright Crown Copyright 2020
|
|
7
|
+
* @license Apache-2.0
|
|
8
|
+
*/
|
|
9
|
+
import TestRegister from "../../lib/TestRegister.mjs";
|
|
10
|
+
|
|
11
|
+
TestRegister.addTests([
|
|
12
|
+
{
|
|
13
|
+
name: "LS47 Encrypt",
|
|
14
|
+
input: "thequickbrownfoxjumped",
|
|
15
|
+
expectedOutput: "(,t74ci78cp/8trx*yesu:alp1wqy",
|
|
16
|
+
recipeConfig: [
|
|
17
|
+
{
|
|
18
|
+
op: "LS47 Encrypt",
|
|
19
|
+
args: ["helloworld", 0, "test"],
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: "LS47 Decrypt",
|
|
25
|
+
input: "(,t74ci78cp/8trx*yesu:alp1wqy",
|
|
26
|
+
expectedOutput: "thequickbrownfoxjumped---test",
|
|
27
|
+
recipeConfig: [
|
|
28
|
+
{
|
|
29
|
+
op: "LS47 Decrypt",
|
|
30
|
+
args: ["helloworld", 0],
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: "LS47 Encrypt",
|
|
36
|
+
input: "thequickbrownfoxjumped",
|
|
37
|
+
expectedOutput: "Letter H is not included in LS47",
|
|
38
|
+
recipeConfig: [
|
|
39
|
+
{
|
|
40
|
+
op: "LS47 Encrypt",
|
|
41
|
+
args: ["Helloworld", 0, "test"],
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
}
|
|
45
|
+
]);
|