From 71c743ff5a6c4f27c9088329bb41211c10845336 Mon Sep 17 00:00:00 2001 From: Cynser <42423063+Cynser@users.noreply.github.com> Date: Wed, 12 Dec 2018 17:34:45 +0000 Subject: [PATCH 01/14] Add Text Encoding Brute Force operation --- src/core/config/Categories.json | 1 + .../operations/TextEncodingBruteForce.mjs | 52 +++++++++++++++++++ test/index.mjs | 1 + .../operations/TextEncodingBruteForce.mjs | 24 +++++++++ 4 files changed, 78 insertions(+) create mode 100644 src/core/operations/TextEncodingBruteForce.mjs create mode 100644 test/tests/operations/TextEncodingBruteForce.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 4fac84c9..9db13647 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -49,6 +49,7 @@ "Change IP format", "Encode text", "Decode text", + "Text Encoding Brute Force", "Swap endianness", "To MessagePack", "From MessagePack", diff --git a/src/core/operations/TextEncodingBruteForce.mjs b/src/core/operations/TextEncodingBruteForce.mjs new file mode 100644 index 00000000..ef2d6500 --- /dev/null +++ b/src/core/operations/TextEncodingBruteForce.mjs @@ -0,0 +1,52 @@ +/** + * @author Cynser + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import cptable from "../vendor/js-codepage/cptable.js"; +import {IO_FORMAT} from "../lib/ChrEnc"; + +/** + * Text Encoding Brute Force operation + */ +class TextEncodingBruteForce extends Operation { + + /** + * TextEncodingBruteForce constructor + */ + constructor() { + super(); + + this.name = "Text Encoding Brute Force"; + this.module = "CharEnc"; + this.description = "Enumerate all possible text encodings for input."; + this.infoURL = "https://wikipedia.org/wiki/Character_encoding"; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const output = [], + charSets = Object.keys(IO_FORMAT); + + for (let i = 0; i < charSets.length; i++) { + let currentEncoding = Utils.printable(charSets[i] + ": ", false); + currentEncoding += cptable.utils.encode(IO_FORMAT[charSets[i]], input); + output.push(currentEncoding); + } + + return output.join("\n"); + } + +} + +export default TextEncodingBruteForce; diff --git a/test/index.mjs b/test/index.mjs index 9c11f6ae..89e09ea4 100644 --- a/test/index.mjs +++ b/test/index.mjs @@ -74,6 +74,7 @@ import "./tests/operations/SetIntersection"; import "./tests/operations/SetUnion"; import "./tests/operations/StrUtils"; import "./tests/operations/SymmetricDifference"; +import "./tests/operations/TextEncodingBruteForce"; import "./tests/operations/ToGeohash.mjs"; import "./tests/operations/TranslateDateTimeFormat"; import "./tests/operations/Magic"; diff --git a/test/tests/operations/TextEncodingBruteForce.mjs b/test/tests/operations/TextEncodingBruteForce.mjs new file mode 100644 index 00000000..5316eb16 --- /dev/null +++ b/test/tests/operations/TextEncodingBruteForce.mjs @@ -0,0 +1,24 @@ +/** + * Text Encoding Brute Force tests. + * + * @author Cynser + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister"; + +TestRegister.addTests([ + { + name: "Text Encoding Brute Force", + input: "Булкі праз ляніва сабаку.", + expectedMatch: /Windows\-1251 Cyrillic \(1251\): Булкі праз ляніва сабаку\./, + recipeConfig: [ + { + op: "Text Encoding Brute Force", + args: [], + }, + ], + } +]); + From 3f7059a2352fc397ec035233f6958877687ceae3 Mon Sep 17 00:00:00 2001 From: Cynser <42423063+Cynser@users.noreply.github.com> Date: Wed, 12 Dec 2018 17:49:11 +0000 Subject: [PATCH 02/14] Remove unnecessary escape character --- test/tests/operations/TextEncodingBruteForce.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tests/operations/TextEncodingBruteForce.mjs b/test/tests/operations/TextEncodingBruteForce.mjs index 5316eb16..e79b24af 100644 --- a/test/tests/operations/TextEncodingBruteForce.mjs +++ b/test/tests/operations/TextEncodingBruteForce.mjs @@ -12,7 +12,7 @@ TestRegister.addTests([ { name: "Text Encoding Brute Force", input: "Булкі праз ляніва сабаку.", - expectedMatch: /Windows\-1251 Cyrillic \(1251\): Булкі праз ляніва сабаку\./, + expectedMatch: /Windows-1251 Cyrillic \(1251\): Булкі праз ляніва сабаку\./, recipeConfig: [ { op: "Text Encoding Brute Force", From dcff8971e8ebaf9e60d6d1900e64c851d70c11c2 Mon Sep 17 00:00:00 2001 From: Jarmo van Lenthe Date: Fri, 14 Dec 2018 22:29:51 +0100 Subject: [PATCH 03/14] Added simple A1Z26 'cipher' --- src/core/config/Categories.json | 2 + src/core/operations/A1Z26CipherDecode.mjs | 63 +++++++++++++++++++++++ src/core/operations/A1Z26CipherEncode.mjs | 61 ++++++++++++++++++++++ test/tests/operations/Ciphers.mjs | 33 ++++++++++++ 4 files changed, 159 insertions(+) create mode 100644 src/core/operations/A1Z26CipherDecode.mjs create mode 100644 src/core/operations/A1Z26CipherEncode.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 4fac84c9..e9fe3399 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -86,6 +86,8 @@ "Bifid Cipher Decode", "Affine Cipher Encode", "Affine Cipher Decode", + "A1Z26 Cipher Encode", + "A1Z26 Cipher Decode", "Atbash Cipher", "Substitute", "Derive PBKDF2 key", diff --git a/src/core/operations/A1Z26CipherDecode.mjs b/src/core/operations/A1Z26CipherDecode.mjs new file mode 100644 index 00000000..183bf047 --- /dev/null +++ b/src/core/operations/A1Z26CipherDecode.mjs @@ -0,0 +1,63 @@ +/** + * @author Jarmo van Lenthe [github.com/jarmovanlenthe] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {DELIM_OPTIONS} from "../lib/Delim"; +import OperationError from "../errors/OperationError"; + +/** + * A1Z26 Cipher Decode operation + */ +class A1Z26CipherDecode extends Operation { + + /** + * A1Z26CipherDecode constructor + */ + constructor() { + super(); + + this.name = "A1Z26 Cipher Decode"; + this.module = "Ciphers"; + this.description = "Converts alphabet order numbers into their corresponding alphabet character.

e.g. 1 becomes a and 2 becomes b."; + this.infoURL = ""; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + name: "Delimiter", + type: "option", + value: DELIM_OPTIONS + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const delim = Utils.charRep(args[0] || "Space"); + + if (input.length === 0) { + return []; + } + + let bites = input.split(delim), + latin1 = ""; + for (let i = 0; i < bites.length; i++) { + if (bites[i] < 1 || bites[i] > 26) { + throw new OperationError("Error: all numbers must be between 1 and 26."); + } + latin1 += Utils.chr(parseInt(bites[i], 10) + 96); + } + return latin1; + } + +} + +export default A1Z26CipherDecode; diff --git a/src/core/operations/A1Z26CipherEncode.mjs b/src/core/operations/A1Z26CipherEncode.mjs new file mode 100644 index 00000000..1abcb900 --- /dev/null +++ b/src/core/operations/A1Z26CipherEncode.mjs @@ -0,0 +1,61 @@ +/** + * @author Jarmo van Lenthe [github.com/jarmovanlenthe] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {DELIM_OPTIONS} from "../lib/Delim"; + +/** + * A1Z26 Cipher Encode operation + */ +class A1Z26CipherEncode extends Operation { + + /** + * A1Z26CipherEncode constructor + */ + constructor() { + super(); + + this.name = "A1Z26 Cipher Encode"; + this.module = "Ciphers"; + this.description = "Converts alphabet characters into their corresponding alphabet order number.

e.g. a becomes 1 and b becomes 2.

Non-alphabet characters are dropped."; + this.infoURL = ""; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + name: "Delimiter", + type: "option", + value: DELIM_OPTIONS + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const delim = Utils.charRep(args[0] || "Space"); + let output = ""; + + const sanitizedinput = input.toLowerCase(), + charcode = Utils.strToCharcode(sanitizedinput); + + for (let i = 0; i < charcode.length; i++) { + let ordinal = charcode[i] - 96; + + if (ordinal > 0 && ordinal <= 26) { + output += ordinal.toString(10) + delim; + } + } + return output.slice(0, -delim.length); + } + +} + +export default A1Z26CipherEncode; diff --git a/test/tests/operations/Ciphers.mjs b/test/tests/operations/Ciphers.mjs index fdc98a3a..a46f50a9 100644 --- a/test/tests/operations/Ciphers.mjs +++ b/test/tests/operations/Ciphers.mjs @@ -110,6 +110,39 @@ TestRegister.addTests([ } ], }, + { + name: "A1Z26 Encode: normal", + input: "This is the test sentence.", + expectedOutput: "20 8 9 19 9 19 20 8 5 20 5 19 20 19 5 14 20 5 14 3 5", + recipeConfig: [ + { + op: "A1Z26 Cipher Encode", + args: ["Space"] + } + ], + }, + { + name: "A1Z26 Decode: normal", + input: "20 8 9 19 9 19 20 8 5 20 5 19 20 19 5 14 20 5 14 3 5", + expectedOutput: "thisisthetestsentence", + recipeConfig: [ + { + op: "A1Z26 Cipher Decode", + args: ["Space"] + } + ], + }, + { + name: "A1Z26 Decode: error", + input: "20 8 9 27", + expectedOutput: "Error: all numbers must be between 1 and 26.", + recipeConfig: [ + { + op: "A1Z26 Cipher Decode", + args: ["Space"] + } + ], + }, { name: "Atbash: no input", input: "", From 63593f1b6c37430d520a4ef2a28f4c9dc1a22f9a Mon Sep 17 00:00:00 2001 From: Oliver Grubin Date: Fri, 14 Dec 2018 21:32:44 +0000 Subject: [PATCH 04/14] Fix HMAC operation when hex key has bytes >= 0x80 (#437) Add test vectors from RFC4231 --- src/core/operations/HMAC.mjs | 2 +- test/tests/operations/Hash.mjs | 298 ++++++++++++++++++++++++++++++++- 2 files changed, 298 insertions(+), 2 deletions(-) diff --git a/src/core/operations/HMAC.mjs b/src/core/operations/HMAC.mjs index e013737e..6517c581 100644 --- a/src/core/operations/HMAC.mjs +++ b/src/core/operations/HMAC.mjs @@ -72,7 +72,7 @@ class HMAC extends Operation { msg = Utils.arrayBufferToStr(input, false), hasher = CryptoApi.getHasher(hashFunc); - const mac = CryptoApi.getHmac(CryptoApi.encoder.fromUtf(key), hasher); + const mac = CryptoApi.getHmac(key, hasher); mac.update(msg); return CryptoApi.encoder.toHex(mac.finalize()); } diff --git a/test/tests/operations/Hash.mjs b/test/tests/operations/Hash.mjs index 8e774329..ec4a6dac 100644 --- a/test/tests/operations/Hash.mjs +++ b/test/tests/operations/Hash.mjs @@ -405,7 +405,7 @@ TestRegister.addTests([ ] }, { - name: "HMAC SHA256", + name: "HMAC: SHA256", input: "Hello, World!", expectedOutput: "52589bd80ccfa4acbb3f9512dfaf4f700fa5195008aae0b77a9e47dcca75beac", recipeConfig: [ @@ -415,6 +415,302 @@ TestRegister.addTests([ } ] }, + { + name: "HMAC: RFC4231 Test Case 1 SHA-224", + input: "Hi There", + expectedOutput: "896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"}, "SHA224"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 1 SHA-256", + input: "Hi There", + expectedOutput: "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"}, "SHA256"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 1 SHA-384", + input: "Hi There", + expectedOutput: "afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"}, "SHA384"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 1 SHA-512", + input: "Hi There", + expectedOutput: "87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"}, "SHA512"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 2 SHA-224", + input: "what do ya want for nothing?", + expectedOutput: "a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "4a656665"}, "SHA224"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 2 SHA-256", + input: "what do ya want for nothing?", + expectedOutput: "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "4a656665"}, "SHA256"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 2 SHA-384", + input: "what do ya want for nothing?", + expectedOutput: "af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "4a656665"}, "SHA384"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 2 SHA-512", + input: "what do ya want for nothing?", + expectedOutput: "164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "4a656665"}, "SHA512"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 3 SHA-224", + input: "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + expectedOutput: "7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea", + recipeConfig: [ + { + "op": "From Hex", + "args": ["None"] + }, + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, "SHA224"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 3 SHA-256", + input: "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + expectedOutput: "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe", + recipeConfig: [ + { + "op": "From Hex", + "args": ["None"] + }, + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, "SHA256"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 3 SHA-384", + input: "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + expectedOutput: "88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b2a5ab39dc13814b94e3ab6e101a34f27", + recipeConfig: [ + { + "op": "From Hex", + "args": ["None"] + }, + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, "SHA384"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 3 SHA-512", + input: "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + expectedOutput: "fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb", + recipeConfig: [ + { + "op": "From Hex", + "args": ["None"] + }, + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, "SHA512"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 4 SHA-224", + input: "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", + expectedOutput: "6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a", + recipeConfig: [ + { + "op": "From Hex", + "args": ["None"] + }, + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "0102030405060708090a0b0c0d0e0f10111213141516171819"}, "SHA224"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 4 SHA-256", + input: "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", + expectedOutput: "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b", + recipeConfig: [ + { + "op": "From Hex", + "args": ["None"] + }, + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "0102030405060708090a0b0c0d0e0f10111213141516171819"}, "SHA256"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 4 SHA-384", + input: "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", + expectedOutput: "3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e6801dd23c4a7d679ccf8a386c674cffb", + recipeConfig: [ + { + "op": "From Hex", + "args": ["None"] + }, + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "0102030405060708090a0b0c0d0e0f10111213141516171819"}, "SHA384"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 4 SHA-512", + input: "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", + expectedOutput: "b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd", + recipeConfig: [ + { + "op": "From Hex", + "args": ["None"] + }, + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "0102030405060708090a0b0c0d0e0f10111213141516171819"}, "SHA512"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 6 SHA-224", + input: "Test Using Larger Than Block-Size Key - Hash Key First", + expectedOutput: "95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, "SHA224"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 6 SHA-256", + input: "Test Using Larger Than Block-Size Key - Hash Key First", + expectedOutput: "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, "SHA256"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 6 SHA-384", + input: "Test Using Larger Than Block-Size Key - Hash Key First", + expectedOutput: "4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c60c2ef6ab4030fe8296248df163f44952", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, "SHA384"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 6 SHA-512", + input: "Test Using Larger Than Block-Size Key - Hash Key First", + expectedOutput: "80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, "SHA512"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 7 SHA-224", + input: "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", + expectedOutput: "3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, "SHA224"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 7 SHA-256", + input: "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", + expectedOutput: "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, "SHA256"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 7 SHA-384", + input: "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", + expectedOutput: "6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5a678cc31e799176d3860e6110c46523e", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, "SHA384"] + } + ] + }, + { + name: "HMAC: RFC4231 Test Case 7 SHA-512", + input: "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", + expectedOutput: "e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58", + recipeConfig: [ + { + "op": "HMAC", + "args": [{"option": "Hex", "string": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, "SHA512"] + } + ] + }, { name: "MD5: Complex bytes", input: "10dc10e32010de10d010dc10d810d910d010e12e", From b4a586c0b9cf635c41a6f36a27925d3086d90d83 Mon Sep 17 00:00:00 2001 From: Jarmo van Lenthe Date: Fri, 14 Dec 2018 22:35:43 +0100 Subject: [PATCH 05/14] Some lets to consts and removing of trailing spaces from grunt lint --- src/core/operations/A1Z26CipherDecode.mjs | 6 +++--- src/core/operations/A1Z26CipherEncode.mjs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/operations/A1Z26CipherDecode.mjs b/src/core/operations/A1Z26CipherDecode.mjs index 183bf047..2a9f9ce7 100644 --- a/src/core/operations/A1Z26CipherDecode.mjs +++ b/src/core/operations/A1Z26CipherDecode.mjs @@ -42,13 +42,13 @@ class A1Z26CipherDecode extends Operation { */ run(input, args) { const delim = Utils.charRep(args[0] || "Space"); - + if (input.length === 0) { return []; } - let bites = input.split(delim), - latin1 = ""; + const bites = input.split(delim); + let latin1 = ""; for (let i = 0; i < bites.length; i++) { if (bites[i] < 1 || bites[i] > 26) { throw new OperationError("Error: all numbers must be between 1 and 26."); diff --git a/src/core/operations/A1Z26CipherEncode.mjs b/src/core/operations/A1Z26CipherEncode.mjs index 1abcb900..d1202d83 100644 --- a/src/core/operations/A1Z26CipherEncode.mjs +++ b/src/core/operations/A1Z26CipherEncode.mjs @@ -42,12 +42,12 @@ class A1Z26CipherEncode extends Operation { run(input, args) { const delim = Utils.charRep(args[0] || "Space"); let output = ""; - + const sanitizedinput = input.toLowerCase(), charcode = Utils.strToCharcode(sanitizedinput); for (let i = 0; i < charcode.length; i++) { - let ordinal = charcode[i] - 96; + const ordinal = charcode[i] - 96; if (ordinal > 0 && ordinal <= 26) { output += ordinal.toString(10) + delim; From 31cbf8ccccc295d0ed6b472e890876d8c5da9ae7 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Sat, 15 Dec 2018 00:16:23 +0000 Subject: [PATCH 06/14] 8.12.4 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4f1be0a3..3f1f599a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "8.12.3", + "version": "8.12.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 4fac8034..338aced6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "8.12.3", + "version": "8.12.4", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 50f078cc45f221418519bb5e573d704e8a760c6d Mon Sep 17 00:00:00 2001 From: n1474335 Date: Sat, 15 Dec 2018 00:26:15 +0000 Subject: [PATCH 07/14] Updated CHANGELOG --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87a81bdd..a65fc145 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Changelog All major and minor version changes will be documented in this file. Details of patch-level version changes can be found in [commit messages](https://github.com/gchq/CyberChef/commits/master). +### [8.13.0] - 2018-12-15 +- 'A1Z26 Cipher Encode' and 'A1Z26 Cipher Decode' operations added [@jarmovanlenthe] | [#441] + ### [8.12.0] - 2018-11-21 - 'Citrix CTX1 Encode' and 'Citrix CTX1 Decode' operations added [@bwhitn] | [#428] @@ -20,7 +23,7 @@ All major and minor version changes will be documented in this file. Details of - 'JWT Sign', 'JWT Verify' and 'JWT Decode' operations added [@GCHQ77703] | [#348] ### [8.6.0] - 2018-08-29 -- 'To Geohash' and 'From Geohash' operations added [@GCHQ77703] | [#344] +- 'To Geohash' and 'From Geohash' operations added [@GCHQ77703] | [#344] ### [8.5.0] - 2018-08-23 - 'To Braille' and 'From Braille' operations added [@n1474335] | [#255] @@ -66,6 +69,7 @@ All major and minor version changes will be documented in this file. Details of +[8.13.0]: https://github.com/gchq/CyberChef/releases/tag/v8.13.0 [8.12.0]: https://github.com/gchq/CyberChef/releases/tag/v8.12.0 [8.11.0]: https://github.com/gchq/CyberChef/releases/tag/v8.11.0 [8.10.0]: https://github.com/gchq/CyberChef/releases/tag/v8.10.0 @@ -96,6 +100,7 @@ All major and minor version changes will be documented in this file. Details of [@arnydo]: https://github.com/arnydo [@klaxon1]: https://github.com/klaxon1 [@bwhitn]: https://github.com/bwhitn +[@jarmovanlenthe]: https://github.com/jarmovanlenthe [#95]: https://github.com/gchq/CyberChef/pull/299 [#173]: https://github.com/gchq/CyberChef/pull/173 @@ -119,3 +124,4 @@ All major and minor version changes will be documented in this file. Details of [#387]: https://github.com/gchq/CyberChef/pull/387 [#394]: https://github.com/gchq/CyberChef/pull/394 [#428]: https://github.com/gchq/CyberChef/pull/428 +[#441]: https://github.com/gchq/CyberChef/pull/441 From 79b9b63982ba612bc426f50a54b6137af08831ec Mon Sep 17 00:00:00 2001 From: n1474335 Date: Sat, 15 Dec 2018 00:26:41 +0000 Subject: [PATCH 08/14] 8.13.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3f1f599a..07446032 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "8.12.4", + "version": "8.13.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 338aced6..48751e21 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "8.12.4", + "version": "8.13.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 22454ae842769fa819cde142b609d08e9db6be25 Mon Sep 17 00:00:00 2001 From: tcode2k16 Date: Mon, 17 Dec 2018 12:37:00 +0800 Subject: [PATCH 09/14] Add "To Base62" and "From Base62" operations --- src/core/config/Categories.json | 2 + src/core/operations/FromBase62.mjs | 52 ++++++++++++++++++++ src/core/operations/ToBase62.mjs | 54 ++++++++++++++++++++ test/index.mjs | 1 + test/tests/operations/Base62.mjs | 79 ++++++++++++++++++++++++++++++ 5 files changed, 188 insertions(+) create mode 100644 src/core/operations/FromBase62.mjs create mode 100644 src/core/operations/ToBase62.mjs create mode 100644 test/tests/operations/Base62.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index e9fe3399..0a3a5f6e 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -18,6 +18,8 @@ "From Binary", "To Octal", "From Octal", + "To Base62", + "From Base62", "To Base64", "From Base64", "Show Base64 offsets", diff --git a/src/core/operations/FromBase62.mjs b/src/core/operations/FromBase62.mjs new file mode 100644 index 00000000..5d56b3b7 --- /dev/null +++ b/src/core/operations/FromBase62.mjs @@ -0,0 +1,52 @@ +/** + * @author tcode2k16 [tcode2k16@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import BigNumber from "bignumber.js"; +import Utils from "../Utils"; + + +/** + * From Base62 operation + */ +class FromBase62 extends Operation { + + /** + * FromBase62 constructor + */ + constructor() { + super(); + + this.name = "From Base62"; + this.module = "Default"; + this.description = "decode base62 string"; + this.infoURL = "https://en.wikipedia.org/wiki/List_of_numeral_systems"; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + if (input.length < 1) return ""; + const ALPHABET = Utils.expandAlphRange("0-9A-Za-z").join(""); + const BN = BigNumber.clone({ ALPHABET }); + + const re = new RegExp("[^" + ALPHABET.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g"); + input = input.replace(re, ""); + + const number = new BN(input, 62); + + return Utils.byteArrayToUtf8(Utils.convertToByteArray(number.toString(16), "Hex")); + } + +} + +export default FromBase62; diff --git a/src/core/operations/ToBase62.mjs b/src/core/operations/ToBase62.mjs new file mode 100644 index 00000000..a52679ef --- /dev/null +++ b/src/core/operations/ToBase62.mjs @@ -0,0 +1,54 @@ +/** + * @author tcode2k16 [tcode2k16@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import BigNumber from "bignumber.js"; +import Utils from "../Utils"; +import {toHexFast} from "../lib/Hex"; + +/** + * To Base62 operation + */ +class ToBase62 extends Operation { + + /** + * ToBase62 constructor + */ + constructor() { + super(); + + this.name = "To Base62"; + this.module = "Default"; + this.description = "encode string to base62"; + this.infoURL = "https://en.wikipedia.org/wiki/List_of_numeral_systems"; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + if (input.length < 1) return ""; + + const ALPHABET = Utils.expandAlphRange("0-9A-Za-z").join(""); + const BN = BigNumber.clone({ ALPHABET }); + + input = Utils.strToByteArray(input); + input = toHexFast(input); + input = input.toUpperCase(); + + const number = new BN(input, 16); + + return number.toString(62); + } + +} + +export default ToBase62; diff --git a/test/index.mjs b/test/index.mjs index 9c11f6ae..9b1caea1 100644 --- a/test/index.mjs +++ b/test/index.mjs @@ -28,6 +28,7 @@ import "./tests/operations/BCD"; import "./tests/operations/BSON"; import "./tests/operations/Base58"; import "./tests/operations/Base64"; +import "./tests/operations/Base62"; import "./tests/operations/BitwiseOp"; import "./tests/operations/ByteRepr"; import "./tests/operations/CartesianProduct"; diff --git a/test/tests/operations/Base62.mjs b/test/tests/operations/Base62.mjs new file mode 100644 index 00000000..e96e4e46 --- /dev/null +++ b/test/tests/operations/Base62.mjs @@ -0,0 +1,79 @@ +/** + * Base62 tests. + * + * @author tcode2k16 [tcode2k16@gmail.com] + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import TestRegister from "../../TestRegister"; + +TestRegister.addTests([ + { + name: "To Base62: nothing", + input: "", + expectedOutput: "", + recipeConfig: [ + { + op: "To Base62", + args: [], + }, + ], + }, + { + name: "To Base62: Hello, World!", + input: "Hello, World!", + expectedOutput: "1wJfrzvdbtXUOlUjUf", + recipeConfig: [ + { + op: "To Base62", + args: [], + }, + ], + }, + { + name: "To Base62: UTF-8", + input: "ნუ პანიკას", + expectedOutput: "BPDNbjoGvDCDzHbKT77eWg0vGQrJuWRXltuRVZ", + recipeConfig: [ + { + op: "To Base62", + args: [], + }, + ], + }, + { + name: "From Base62: nothing", + input: "", + expectedOutput: "", + recipeConfig: [ + { + op: "From Base62", + args: [], + }, + ], + }, + { + name: "From Base62: Hello, World!", + input: "1wJfrzvdbtXUOlUjUf", + expectedOutput: "Hello, World!", + recipeConfig: [ + { + op: "From Base62", + args: [], + }, + ], + }, + { + name: "From Base62: UTF-8", + input: "BPDNbjoGvDCDzHbKT77eWg0vGQrJuWRXltuRVZ", + expectedOutput: "ნუ პანიკას", + recipeConfig: [ + { + op: "From Base62", + args: [], + }, + ], + } +]); From dacb3ef6c3da374ef6aa721675a4b4a697d4fea0 Mon Sep 17 00:00:00 2001 From: Cynser <42423063+Cynser@users.noreply.github.com> Date: Mon, 17 Dec 2018 19:39:12 +0000 Subject: [PATCH 10/14] Added decode option --- .../operations/TextEncodingBruteForce.mjs | 27 +++++++++++++++---- .../operations/TextEncodingBruteForce.mjs | 15 +++++++++-- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/core/operations/TextEncodingBruteForce.mjs b/src/core/operations/TextEncodingBruteForce.mjs index ef2d6500..9c606eaa 100644 --- a/src/core/operations/TextEncodingBruteForce.mjs +++ b/src/core/operations/TextEncodingBruteForce.mjs @@ -26,7 +26,13 @@ class TextEncodingBruteForce extends Operation { this.infoURL = "https://wikipedia.org/wiki/Character_encoding"; this.inputType = "string"; this.outputType = "string"; - this.args = []; + this.args = [ + { + name: "Mode", + type: "option", + value: ["Encode", "Decode"] + } + ]; } /** @@ -36,12 +42,23 @@ class TextEncodingBruteForce extends Operation { */ run(input, args) { const output = [], - charSets = Object.keys(IO_FORMAT); + charSets = Object.keys(IO_FORMAT), + mode = args[0]; for (let i = 0; i < charSets.length; i++) { - let currentEncoding = Utils.printable(charSets[i] + ": ", false); - currentEncoding += cptable.utils.encode(IO_FORMAT[charSets[i]], input); - output.push(currentEncoding); + let currentEncoding = charSets[i] + ": "; + + try { + if (mode === "Decode") { + currentEncoding += cptable.utils.decode(IO_FORMAT[charSets[i]], input); + } else { + currentEncoding += cptable.utils.encode(IO_FORMAT[charSets[i]], input); + } + } catch (err) { + currentEncoding += "Could not decode."; + } + + output.push(Utils.printable(currentEncoding, true)); } return output.join("\n"); diff --git a/test/tests/operations/TextEncodingBruteForce.mjs b/test/tests/operations/TextEncodingBruteForce.mjs index e79b24af..3b16453d 100644 --- a/test/tests/operations/TextEncodingBruteForce.mjs +++ b/test/tests/operations/TextEncodingBruteForce.mjs @@ -10,13 +10,24 @@ import TestRegister from "../../TestRegister"; TestRegister.addTests([ { - name: "Text Encoding Brute Force", + name: "Text Encoding Brute Force - Encode", input: "Булкі праз ляніва сабаку.", expectedMatch: /Windows-1251 Cyrillic \(1251\): Булкі праз ляніва сабаку\./, recipeConfig: [ { op: "Text Encoding Brute Force", - args: [], + args: ["Encode"], + }, + ], + }, + { + name: "Text Encoding Brute Force - Decode", + input: "Áóëê³ ïðàç ëÿí³âà ñàáàêó.", + expectedMatch: /Windows-1251 Cyrillic \(1251\): Булкі праз ляніва сабаку\./, + recipeConfig: [ + { + op: "Text Encoding Brute Force", + args: ["Decode"], }, ], } From d89d79116c827ce6dc6ecd36a2b990423c0d9874 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 18 Dec 2018 12:19:42 +0000 Subject: [PATCH 11/14] Cleaned up Base62 ops and updated CHANGELOG --- CHANGELOG.md | 7 +++++++ src/core/config/Categories.json | 4 ++-- src/core/operations/FromBase62.mjs | 22 ++++++++++++++-------- src/core/operations/ToBase62.mjs | 18 +++++++++++------- test/tests/operations/Base62.mjs | 12 ++++++------ 5 files changed, 40 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a65fc145..15943e7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All major and minor version changes will be documented in this file. Details of patch-level version changes can be found in [commit messages](https://github.com/gchq/CyberChef/commits/master). + +### [8.14.0] - 2018-12-18 +- 'To Base62' and 'From Base62' operations added [@tcode2k16] | [#443] + ### [8.13.0] - 2018-12-15 - 'A1Z26 Cipher Encode' and 'A1Z26 Cipher Decode' operations added [@jarmovanlenthe] | [#441] @@ -69,6 +73,7 @@ All major and minor version changes will be documented in this file. Details of +[8.14.0]: https://github.com/gchq/CyberChef/releases/tag/v8.14.0 [8.13.0]: https://github.com/gchq/CyberChef/releases/tag/v8.13.0 [8.12.0]: https://github.com/gchq/CyberChef/releases/tag/v8.12.0 [8.11.0]: https://github.com/gchq/CyberChef/releases/tag/v8.11.0 @@ -101,6 +106,7 @@ All major and minor version changes will be documented in this file. Details of [@klaxon1]: https://github.com/klaxon1 [@bwhitn]: https://github.com/bwhitn [@jarmovanlenthe]: https://github.com/jarmovanlenthe +[@tcode2k16]: https://github.com/tcode2k16 [#95]: https://github.com/gchq/CyberChef/pull/299 [#173]: https://github.com/gchq/CyberChef/pull/173 @@ -125,3 +131,4 @@ All major and minor version changes will be documented in this file. Details of [#394]: https://github.com/gchq/CyberChef/pull/394 [#428]: https://github.com/gchq/CyberChef/pull/428 [#441]: https://github.com/gchq/CyberChef/pull/441 +[#443]: https://github.com/gchq/CyberChef/pull/443 diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 0a3a5f6e..d4e815ac 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -18,8 +18,6 @@ "From Binary", "To Octal", "From Octal", - "To Base62", - "From Base62", "To Base64", "From Base64", "Show Base64 offsets", @@ -27,6 +25,8 @@ "From Base32", "To Base58", "From Base58", + "To Base62", + "From Base62", "To Base85", "From Base85", "To Base", diff --git a/src/core/operations/FromBase62.mjs b/src/core/operations/FromBase62.mjs index 5d56b3b7..525f2e2f 100644 --- a/src/core/operations/FromBase62.mjs +++ b/src/core/operations/FromBase62.mjs @@ -22,21 +22,27 @@ class FromBase62 extends Operation { this.name = "From Base62"; this.module = "Default"; - this.description = "decode base62 string"; - this.infoURL = "https://en.wikipedia.org/wiki/List_of_numeral_systems"; + this.description = "Base62 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. The high number base results in shorter strings than with the decimal or hexadecimal system."; + this.infoURL = "https://wikipedia.org/wiki/List_of_numeral_systems"; this.inputType = "string"; - this.outputType = "string"; - this.args = []; + this.outputType = "byteArray"; + this.args = [ + { + name: "Alphabet", + type: "string", + value: "0-9A-Za-z" + } + ]; } /** * @param {string} input * @param {Object[]} args - * @returns {string} + * @returns {byteArray} */ run(input, args) { - if (input.length < 1) return ""; - const ALPHABET = Utils.expandAlphRange("0-9A-Za-z").join(""); + if (input.length < 1) return []; + const ALPHABET = Utils.expandAlphRange(args[0]).join(""); const BN = BigNumber.clone({ ALPHABET }); const re = new RegExp("[^" + ALPHABET.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g"); @@ -44,7 +50,7 @@ class FromBase62 extends Operation { const number = new BN(input, 62); - return Utils.byteArrayToUtf8(Utils.convertToByteArray(number.toString(16), "Hex")); + return Utils.convertToByteArray(number.toString(16), "Hex"); } } diff --git a/src/core/operations/ToBase62.mjs b/src/core/operations/ToBase62.mjs index a52679ef..3f615db2 100644 --- a/src/core/operations/ToBase62.mjs +++ b/src/core/operations/ToBase62.mjs @@ -22,11 +22,17 @@ class ToBase62 extends Operation { this.name = "To Base62"; this.module = "Default"; - this.description = "encode string to base62"; + this.description = "Base62 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. The high number base results in shorter strings than with the decimal or hexadecimal system."; this.infoURL = "https://en.wikipedia.org/wiki/List_of_numeral_systems"; - this.inputType = "string"; + this.inputType = "byteArray"; this.outputType = "string"; - this.args = []; + this.args = [ + { + name: "Alphabet", + type: "string", + value: "0-9A-Za-z" + } + ]; } /** @@ -37,12 +43,10 @@ class ToBase62 extends Operation { run(input, args) { if (input.length < 1) return ""; - const ALPHABET = Utils.expandAlphRange("0-9A-Za-z").join(""); + const ALPHABET = Utils.expandAlphRange(args[0]).join(""); const BN = BigNumber.clone({ ALPHABET }); - input = Utils.strToByteArray(input); - input = toHexFast(input); - input = input.toUpperCase(); + input = toHexFast(input).toUpperCase(); const number = new BN(input, 16); diff --git a/test/tests/operations/Base62.mjs b/test/tests/operations/Base62.mjs index e96e4e46..8bf41b36 100644 --- a/test/tests/operations/Base62.mjs +++ b/test/tests/operations/Base62.mjs @@ -17,7 +17,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "To Base62", - args: [], + args: ["0-9A-Za-z"], }, ], }, @@ -28,7 +28,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "To Base62", - args: [], + args: ["0-9A-Za-z"], }, ], }, @@ -39,7 +39,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "To Base62", - args: [], + args: ["0-9A-Za-z"], }, ], }, @@ -50,7 +50,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "From Base62", - args: [], + args: ["0-9A-Za-z"], }, ], }, @@ -61,7 +61,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "From Base62", - args: [], + args: ["0-9A-Za-z"], }, ], }, @@ -72,7 +72,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "From Base62", - args: [], + args: ["0-9A-Za-z"], }, ], } From 56f830240204db8a70990ec45445a33829e90901 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 18 Dec 2018 12:20:03 +0000 Subject: [PATCH 12/14] 8.14.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 07446032..eb66cd91 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "8.13.0", + "version": "8.14.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 48751e21..9565b4e0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "8.13.0", + "version": "8.14.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 076a1f97c29ab3857b5801bf1d1c0991a432dfc3 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 18 Dec 2018 13:50:10 +0000 Subject: [PATCH 13/14] Tidied up 'Text Encoding Brute Force' operations and updated CHANGELOG --- CHANGELOG.md | 6 +++ babel.config.js | 2 +- .../operations/TextEncodingBruteForce.mjs | 49 ++++++++++++++----- src/core/operations/ToBase62.mjs | 2 +- .../operations/TextEncodingBruteForce.mjs | 4 +- 5 files changed, 46 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15943e7e..6355831e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All major and minor version changes will be documented in this file. Details of patch-level version changes can be found in [commit messages](https://github.com/gchq/CyberChef/commits/master). +### [8.15.0] - 2018-12-18 +- 'Text Encoding Brute Force' operation added [@Cynser] | [#439] + ### [8.14.0] - 2018-12-18 - 'To Base62' and 'From Base62' operations added [@tcode2k16] | [#443] @@ -73,6 +76,7 @@ All major and minor version changes will be documented in this file. Details of +[8.15.0]: https://github.com/gchq/CyberChef/releases/tag/v8.15.0 [8.14.0]: https://github.com/gchq/CyberChef/releases/tag/v8.14.0 [8.13.0]: https://github.com/gchq/CyberChef/releases/tag/v8.13.0 [8.12.0]: https://github.com/gchq/CyberChef/releases/tag/v8.12.0 @@ -107,6 +111,7 @@ All major and minor version changes will be documented in this file. Details of [@bwhitn]: https://github.com/bwhitn [@jarmovanlenthe]: https://github.com/jarmovanlenthe [@tcode2k16]: https://github.com/tcode2k16 +[@Cynser]: https://github.com/Cynser [#95]: https://github.com/gchq/CyberChef/pull/299 [#173]: https://github.com/gchq/CyberChef/pull/173 @@ -130,5 +135,6 @@ All major and minor version changes will be documented in this file. Details of [#387]: https://github.com/gchq/CyberChef/pull/387 [#394]: https://github.com/gchq/CyberChef/pull/394 [#428]: https://github.com/gchq/CyberChef/pull/428 +[#439]: https://github.com/gchq/CyberChef/pull/439 [#441]: https://github.com/gchq/CyberChef/pull/441 [#443]: https://github.com/gchq/CyberChef/pull/443 diff --git a/babel.config.js b/babel.config.js index 2362c42a..5459f6c8 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,7 +1,7 @@ module.exports = function(api) { api.cache.forever(); - return { + return { "presets": [ ["@babel/preset-env", { "targets": { diff --git a/src/core/operations/TextEncodingBruteForce.mjs b/src/core/operations/TextEncodingBruteForce.mjs index 9c606eaa..3919dcd9 100644 --- a/src/core/operations/TextEncodingBruteForce.mjs +++ b/src/core/operations/TextEncodingBruteForce.mjs @@ -1,5 +1,6 @@ /** * @author Cynser + * @author n1474335 [n1474335@gmail.com] * @copyright Crown Copyright 2018 * @license Apache-2.0 */ @@ -22,10 +23,18 @@ class TextEncodingBruteForce extends Operation { this.name = "Text Encoding Brute Force"; this.module = "CharEnc"; - this.description = "Enumerate all possible text encodings for input."; + this.description = [ + "Enumerates all supported text encodings for the input, allowing you to quickly spot the correct one.", + "

", + "Supported charsets are:", + "
    ", + Object.keys(IO_FORMAT).map(e => `
  • ${e}
  • `).join("\n"), + "
" + ].join("\n"); this.infoURL = "https://wikipedia.org/wiki/Character_encoding"; this.inputType = "string"; - this.outputType = "string"; + this.outputType = "json"; + this.presentType = "html"; this.args = [ { name: "Mode", @@ -38,30 +47,44 @@ class TextEncodingBruteForce extends Operation { /** * @param {string} input * @param {Object[]} args - * @returns {string} + * @returns {json} */ run(input, args) { - const output = [], - charSets = Object.keys(IO_FORMAT), + const output = {}, + charsets = Object.keys(IO_FORMAT), mode = args[0]; - for (let i = 0; i < charSets.length; i++) { - let currentEncoding = charSets[i] + ": "; - + charsets.forEach(charset => { try { if (mode === "Decode") { - currentEncoding += cptable.utils.decode(IO_FORMAT[charSets[i]], input); + output[charset] = cptable.utils.decode(IO_FORMAT[charset], input); } else { - currentEncoding += cptable.utils.encode(IO_FORMAT[charSets[i]], input); + output[charset] = Utils.arrayBufferToStr(cptable.utils.encode(IO_FORMAT[charset], input)); } } catch (err) { - currentEncoding += "Could not decode."; + output[charset] = "Could not decode."; } + }); - output.push(Utils.printable(currentEncoding, true)); + return output; + } + + /** + * Displays the encodings in an HTML table for web apps. + * + * @param {Object[]} encodings + * @returns {html} + */ + present(encodings) { + let table = ""; + + for (const enc in encodings) { + const value = Utils.printable(encodings[enc], true); + table += ``; } - return output.join("\n"); + table += "
EncodingValue
${enc}${value}
"; + return table; } } diff --git a/src/core/operations/ToBase62.mjs b/src/core/operations/ToBase62.mjs index 3f615db2..51f89ecd 100644 --- a/src/core/operations/ToBase62.mjs +++ b/src/core/operations/ToBase62.mjs @@ -23,7 +23,7 @@ class ToBase62 extends Operation { this.name = "To Base62"; this.module = "Default"; this.description = "Base62 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. The high number base results in shorter strings than with the decimal or hexadecimal system."; - this.infoURL = "https://en.wikipedia.org/wiki/List_of_numeral_systems"; + this.infoURL = "https://wikipedia.org/wiki/List_of_numeral_systems"; this.inputType = "byteArray"; this.outputType = "string"; this.args = [ diff --git a/test/tests/operations/TextEncodingBruteForce.mjs b/test/tests/operations/TextEncodingBruteForce.mjs index 3b16453d..22e8f7c5 100644 --- a/test/tests/operations/TextEncodingBruteForce.mjs +++ b/test/tests/operations/TextEncodingBruteForce.mjs @@ -12,7 +12,7 @@ TestRegister.addTests([ { name: "Text Encoding Brute Force - Encode", input: "Булкі праз ляніва сабаку.", - expectedMatch: /Windows-1251 Cyrillic \(1251\): Булкі праз ляніва сабаку\./, + expectedMatch: /Windows-1251 Cyrillic \(1251\).{1,10}Булкі праз ляніва сабаку\./, recipeConfig: [ { op: "Text Encoding Brute Force", @@ -23,7 +23,7 @@ TestRegister.addTests([ { name: "Text Encoding Brute Force - Decode", input: "Áóëê³ ïðàç ëÿí³âà ñàáàêó.", - expectedMatch: /Windows-1251 Cyrillic \(1251\): Булкі праз ляніва сабаку\./, + expectedMatch: /Windows-1251 Cyrillic \(1251\).{1,10}Булкі праз ляніва сабаку\./, recipeConfig: [ { op: "Text Encoding Brute Force", From 8ab56a29ac9473a8a68ad24d6c0ff33669170e25 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 18 Dec 2018 13:50:30 +0000 Subject: [PATCH 14/14] 8.15.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index eb66cd91..5e20c8bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "8.14.0", + "version": "8.15.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 9565b4e0..3505cfa2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "8.14.0", + "version": "8.15.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef",