mirror of
https://github.com/gchq/CyberChef
synced 2025-12-05 23:53:27 +00:00
Compare commits
105 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ecde9fd2a | ||
|
|
320f79fe0d | ||
|
|
157346b055 | ||
|
|
904c08c436 | ||
|
|
fa238545a0 | ||
|
|
3f85c32c7c | ||
|
|
55809b2e87 | ||
|
|
5c32c1bdaa | ||
|
|
f84c11f63d | ||
|
|
2bcfb693b7 | ||
|
|
897d2bef6e | ||
|
|
0a3d219ad5 | ||
|
|
ba0dfe91c3 | ||
|
|
bf4e62b4b7 | ||
|
|
657f8940fa | ||
|
|
74d629c491 | ||
|
|
130e9d8192 | ||
|
|
0fb3743b6d | ||
|
|
a19aea1516 | ||
|
|
137f8d9471 | ||
|
|
1f57f1f000 | ||
|
|
468071ee98 | ||
|
|
23403f55a5 | ||
|
|
c25cf44d92 | ||
|
|
e5644b5712 | ||
|
|
9321b79d81 | ||
|
|
e97d535ff8 | ||
|
|
7589361e58 | ||
|
|
f15ef81693 | ||
|
|
d5f4968664 | ||
|
|
74e9edbccf | ||
|
|
51229d85cb | ||
|
|
b979b051cb | ||
|
|
17cf154bc2 | ||
|
|
c7f6954b97 | ||
|
|
9ccc1613cf | ||
|
|
9730ce1f6a | ||
|
|
55a7981547 | ||
|
|
2d99c365dd | ||
|
|
59d8be511a | ||
|
|
8349ffc001 | ||
|
|
c1368c4ecb | ||
|
|
c6935e040d | ||
|
|
f79c3ae91a | ||
|
|
bc27cd2772 | ||
|
|
2b02c44ca4 | ||
|
|
59fe8d1c4b | ||
|
|
9a5d62c4c3 | ||
|
|
9fa82150ee | ||
|
|
d7561ec208 | ||
|
|
743b834f6d | ||
|
|
0658836f87 | ||
|
|
a4e20c7059 | ||
|
|
d77f8ba747 | ||
|
|
78d35ecec3 | ||
|
|
c79bf5caaf | ||
|
|
66cbc6908a | ||
|
|
c04f409d23 | ||
|
|
1a9833132d | ||
|
|
9c3ddca269 | ||
|
|
72889d1c20 | ||
|
|
6c5433b226 | ||
|
|
31a7f83b82 | ||
|
|
39143fa6a1 | ||
|
|
ebe2a29543 | ||
|
|
1e83e0e935 | ||
|
|
fe9eb08648 | ||
|
|
2255c5b360 | ||
|
|
c046cf5695 | ||
|
|
3086c25079 | ||
|
|
3700780d14 | ||
|
|
5b134d7e9e | ||
|
|
58b1fb8de5 | ||
|
|
c0bd6645ce | ||
|
|
cb023089bb | ||
|
|
5a507aa1ba | ||
|
|
d5ffbbb14c | ||
|
|
fa30f597ad | ||
|
|
ed8bd34915 | ||
|
|
5c72791279 | ||
|
|
142f91425c | ||
|
|
d6344760ec | ||
|
|
64c009f266 | ||
|
|
a73decc792 | ||
|
|
f332ca4617 | ||
|
|
937791d33d | ||
|
|
a63a130723 | ||
|
|
0f1175bf15 | ||
|
|
e4db23f857 | ||
|
|
32e7dd030e | ||
|
|
e33950961e | ||
|
|
5d65cb419f | ||
|
|
536053d5f9 | ||
|
|
8e57354307 | ||
|
|
126debf44e | ||
|
|
674649ca7f | ||
|
|
1a9a070c3b | ||
|
|
32bee35f85 | ||
|
|
a68ce5a5af | ||
|
|
026e9ca9c3 | ||
|
|
f1ce67d79b | ||
|
|
312be4772c | ||
|
|
be97a0062e | ||
|
|
00f0101723 | ||
|
|
f450240094 |
6
.github/workflows/codeql.yml
vendored
6
.github/workflows/codeql.yml
vendored
@@ -22,12 +22,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
6
.github/workflows/master.yml
vendored
6
.github/workflows/master.yml
vendored
@@ -10,10 +10,10 @@ jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set node version
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18.x'
|
||||
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
if: success() && github.ref == 'refs/heads/master'
|
||||
uses: crazy-max/ghaction-github-pages@v2
|
||||
uses: crazy-max/ghaction-github-pages@v3
|
||||
with:
|
||||
target_branch: gh-pages
|
||||
build_dir: ./build/prod
|
||||
|
||||
4
.github/workflows/pull_requests.yml
vendored
4
.github/workflows/pull_requests.yml
vendored
@@ -9,10 +9,10 @@ jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set node version
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18.x'
|
||||
|
||||
|
||||
4
.github/workflows/releases.yml
vendored
4
.github/workflows/releases.yml
vendored
@@ -10,10 +10,10 @@ jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set node version
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18.x'
|
||||
|
||||
|
||||
27
CHANGELOG.md
27
CHANGELOG.md
@@ -13,6 +13,21 @@ All major and minor version changes will be documented in this file. Details of
|
||||
|
||||
## Details
|
||||
|
||||
### [9.52.0] - 2022-11-25
|
||||
- Added 'ChaCha' operation [@joostrijneveld] | [#1466]
|
||||
|
||||
### [9.51.0] - 2022-11-25
|
||||
- Added 'CMAC' operation [@mikecat] | [#1457]
|
||||
|
||||
### [9.50.0] - 2022-11-25
|
||||
- Added 'Shuffle' operation [@mikecat] | [#1472]
|
||||
|
||||
### [9.49.0] - 2022-11-11
|
||||
- Added 'LZ4 Compress' and 'LZ4 Decompress' operations [@n1474335] | [31a7f83]
|
||||
|
||||
### [9.48.0] - 2022-10-14
|
||||
- Added 'LM Hash' and 'NT Hash' operations [@n1474335] [@brun0ne] | [#1427]
|
||||
|
||||
### [9.47.0] - 2022-10-14
|
||||
- Added 'LZMA Decompress' and 'LZMA Compress' operations [@mattnotmitt] | [#1421]
|
||||
|
||||
@@ -318,6 +333,11 @@ All major and minor version changes will be documented in this file. Details of
|
||||
|
||||
|
||||
|
||||
[9.52.0]: https://github.com/gchq/CyberChef/releases/tag/v9.52.0
|
||||
[9.51.0]: https://github.com/gchq/CyberChef/releases/tag/v9.51.0
|
||||
[9.50.0]: https://github.com/gchq/CyberChef/releases/tag/v9.50.0
|
||||
[9.49.0]: https://github.com/gchq/CyberChef/releases/tag/v9.49.0
|
||||
[9.48.0]: https://github.com/gchq/CyberChef/releases/tag/v9.48.0
|
||||
[9.47.0]: https://github.com/gchq/CyberChef/releases/tag/v9.47.0
|
||||
[9.46.0]: https://github.com/gchq/CyberChef/releases/tag/v9.46.0
|
||||
[9.45.0]: https://github.com/gchq/CyberChef/releases/tag/v9.45.0
|
||||
@@ -454,6 +474,8 @@ All major and minor version changes will be documented in this file. Details of
|
||||
[@crespyl]: https://github.com/crespyl
|
||||
[@thomasleplus]: https://github.com/thomasleplus
|
||||
[@valdelaseras]: https://github.com/valdelaseras
|
||||
[@brun0ne]: https://github.com/brun0ne
|
||||
[@joostrijneveld]: https://github.com/joostrijneveld
|
||||
|
||||
[8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7
|
||||
[9a33498]: https://github.com/gchq/CyberChef/commit/9a33498fed26a8df9c9f35f39a78a174bf50a513
|
||||
@@ -461,6 +483,7 @@ All major and minor version changes will be documented in this file. Details of
|
||||
[e9ca4dc]: https://github.com/gchq/CyberChef/commit/e9ca4dc9caf98f33fd986431cd400c88082a42b8
|
||||
[dd18e52]: https://github.com/gchq/CyberChef/commit/dd18e529939078b89867297b181a584e8b2cc7da
|
||||
[a895d1d]: https://github.com/gchq/CyberChef/commit/a895d1d82a2f92d440a0c5eca2bc7c898107b737
|
||||
[31a7f83]: https://github.com/gchq/CyberChef/commit/31a7f83b82e78927f89689f323fcb9185144d6ff
|
||||
|
||||
[#95]: https://github.com/gchq/CyberChef/pull/299
|
||||
[#173]: https://github.com/gchq/CyberChef/pull/173
|
||||
@@ -557,4 +580,8 @@ All major and minor version changes will be documented in this file. Details of
|
||||
[#1250]: https://github.com/gchq/CyberChef/pull/1250
|
||||
[#1308]: https://github.com/gchq/CyberChef/pull/1308
|
||||
[#1421]: https://github.com/gchq/CyberChef/pull/1421
|
||||
[#1427]: https://github.com/gchq/CyberChef/pull/1427
|
||||
[#1472]: https://github.com/gchq/CyberChef/pull/1472
|
||||
[#1457]: https://github.com/gchq/CyberChef/pull/1457
|
||||
[#1466]: https://github.com/gchq/CyberChef/pull/1466
|
||||
|
||||
|
||||
29
package-lock.json
generated
29
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "9.47.1",
|
||||
"version": "9.52.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "cyberchef",
|
||||
"version": "9.47.1",
|
||||
"version": "9.52.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@@ -58,6 +58,7 @@
|
||||
"loglevel": "^1.8.0",
|
||||
"loglevel-message-prefix": "^3.0.0",
|
||||
"lz-string": "^1.4.4",
|
||||
"lz4js": "^0.2.0",
|
||||
"markdown-it": "^13.0.1",
|
||||
"moment": "^2.29.3",
|
||||
"moment-timezone": "^0.5.34",
|
||||
@@ -66,6 +67,7 @@
|
||||
"node-md6": "^0.1.0",
|
||||
"nodom": "^2.4.0",
|
||||
"notepack.io": "^3.0.1",
|
||||
"ntlm": "^0.1.3",
|
||||
"nwmatcher": "^1.4.4",
|
||||
"otp": "0.1.3",
|
||||
"path": "^0.12.7",
|
||||
@@ -9607,6 +9609,11 @@
|
||||
"lz-string": "bin/bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/lz4js": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lz4js/-/lz4js-0.2.0.tgz",
|
||||
"integrity": "sha512-gY2Ia9Lm7Ep8qMiuGRhvUq0Q7qUereeldZPP1PMEJxPtEWHJLqw9pgX68oHajBH0nzJK4MaZEA/YNV3jT8u8Bg=="
|
||||
},
|
||||
"node_modules/make-dir": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||
@@ -10537,6 +10544,14 @@
|
||||
"url": "https://github.com/fb55/nth-check?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/ntlm": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ntlm/-/ntlm-0.1.3.tgz",
|
||||
"integrity": "sha512-pPlHxhAegZP4QAaOYd51vRd6VXTGfF7VLKJwuwN0iEB1aIi3SnqXYuS/bH/6wWBOq+Ehdil49mHm1Nseon085w==",
|
||||
"engines": [
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"node_modules/nwmatcher": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz",
|
||||
@@ -21600,6 +21615,11 @@
|
||||
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz",
|
||||
"integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ=="
|
||||
},
|
||||
"lz4js": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lz4js/-/lz4js-0.2.0.tgz",
|
||||
"integrity": "sha512-gY2Ia9Lm7Ep8qMiuGRhvUq0Q7qUereeldZPP1PMEJxPtEWHJLqw9pgX68oHajBH0nzJK4MaZEA/YNV3jT8u8Bg=="
|
||||
},
|
||||
"make-dir": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||
@@ -22304,6 +22324,11 @@
|
||||
"boolbase": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"ntlm": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ntlm/-/ntlm-0.1.3.tgz",
|
||||
"integrity": "sha512-pPlHxhAegZP4QAaOYd51vRd6VXTGfF7VLKJwuwN0iEB1aIi3SnqXYuS/bH/6wWBOq+Ehdil49mHm1Nseon085w=="
|
||||
},
|
||||
"nwmatcher": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "9.47.1",
|
||||
"version": "9.52.1",
|
||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||
"author": "n1474335 <n1474335@gmail.com>",
|
||||
"homepage": "https://gchq.github.io/CyberChef",
|
||||
@@ -134,6 +134,7 @@
|
||||
"loglevel": "^1.8.0",
|
||||
"loglevel-message-prefix": "^3.0.0",
|
||||
"lz-string": "^1.4.4",
|
||||
"lz4js": "^0.2.0",
|
||||
"markdown-it": "^13.0.1",
|
||||
"moment": "^2.29.3",
|
||||
"moment-timezone": "^0.5.34",
|
||||
@@ -142,6 +143,7 @@
|
||||
"node-md6": "^0.1.0",
|
||||
"nodom": "^2.4.0",
|
||||
"notepack.io": "^3.0.1",
|
||||
"ntlm": "^0.1.3",
|
||||
"nwmatcher": "^1.4.4",
|
||||
"otp": "0.1.3",
|
||||
"path": "^0.12.7",
|
||||
@@ -170,7 +172,7 @@
|
||||
"build": "npx grunt prod",
|
||||
"node": "npx grunt node",
|
||||
"repl": "node --experimental-modules --experimental-json-modules --experimental-specifier-resolution=node --no-warnings src/node/repl.mjs",
|
||||
"test": "npx grunt configTests && node --experimental-modules --experimental-json-modules --no-warnings --no-deprecation tests/node/index.mjs && node --experimental-modules --experimental-json-modules --no-warnings --no-deprecation tests/operations/index.mjs",
|
||||
"test": "npx grunt configTests && node --experimental-modules --experimental-json-modules --no-warnings --no-deprecation --openssl-legacy-provider tests/node/index.mjs && node --experimental-modules --experimental-json-modules --no-warnings --no-deprecation --openssl-legacy-provider tests/operations/index.mjs",
|
||||
"testnodeconsumer": "npx grunt testnodeconsumer",
|
||||
"testui": "npx grunt testui",
|
||||
"testuidev": "npx nightwatch --env=dev",
|
||||
|
||||
@@ -27,6 +27,7 @@ class Ingredient {
|
||||
this.toggleValues = [];
|
||||
this.target = null;
|
||||
this.defaultIndex = 0;
|
||||
this.maxLength = null;
|
||||
this.min = null;
|
||||
this.max = null;
|
||||
this.step = 1;
|
||||
@@ -53,6 +54,7 @@ class Ingredient {
|
||||
this.toggleValues = ingredientConfig.toggleValues;
|
||||
this.target = typeof ingredientConfig.target !== "undefined" ? ingredientConfig.target : null;
|
||||
this.defaultIndex = typeof ingredientConfig.defaultIndex !== "undefined" ? ingredientConfig.defaultIndex : 0;
|
||||
this.maxLength = ingredientConfig.maxLength || null;
|
||||
this.min = ingredientConfig.min;
|
||||
this.max = ingredientConfig.max;
|
||||
this.step = ingredientConfig.step;
|
||||
|
||||
@@ -184,6 +184,7 @@ class Operation {
|
||||
if (ing.disabled) conf.disabled = ing.disabled;
|
||||
if (ing.target) conf.target = ing.target;
|
||||
if (ing.defaultIndex) conf.defaultIndex = ing.defaultIndex;
|
||||
if (ing.maxLength) conf.maxLength = ing.maxLength;
|
||||
if (typeof ing.min === "number") conf.min = ing.min;
|
||||
if (typeof ing.max === "number") conf.max = ing.max;
|
||||
if (ing.step) conf.step = ing.step;
|
||||
|
||||
@@ -206,7 +206,7 @@ class Utils {
|
||||
* Utils.parseEscapedChars("\\n");
|
||||
*/
|
||||
static parseEscapedChars(str) {
|
||||
return str.replace(/\\([bfnrtv'"]|[0-3][0-7]{2}|[0-7]{1,2}|x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]{1,6}\}|\\)/g, function(m, a) {
|
||||
return str.replace(/\\([abfnrtv'"]|[0-3][0-7]{2}|[0-7]{1,2}|x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]{1,6}\}|\\)/g, function(m, a) {
|
||||
switch (a[0]) {
|
||||
case "\\":
|
||||
return "\\";
|
||||
@@ -219,6 +219,8 @@ class Utils {
|
||||
case "6":
|
||||
case "7":
|
||||
return String.fromCharCode(parseInt(a, 8));
|
||||
case "a":
|
||||
return String.fromCharCode(7);
|
||||
case "b":
|
||||
return "\b";
|
||||
case "t":
|
||||
@@ -380,6 +382,70 @@ class Utils {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a byte array to an integer.
|
||||
*
|
||||
* @param {byteArray} byteArray
|
||||
* @param {string} byteorder - "little" or "big"
|
||||
* @returns {integer}
|
||||
*
|
||||
* @example
|
||||
* // returns 67305985
|
||||
* Utils.byteArrayToInt([1, 2, 3, 4], "little");
|
||||
*
|
||||
* // returns 16909060
|
||||
* Utils.byteArrayToInt([1, 2, 3, 4], "big");
|
||||
*/
|
||||
static byteArrayToInt(byteArray, byteorder) {
|
||||
let value = 0;
|
||||
if (byteorder === "big") {
|
||||
for (let i = 0; i < byteArray.length; i++) {
|
||||
value = (value * 256) + byteArray[i];
|
||||
}
|
||||
} else {
|
||||
for (let i = byteArray.length - 1; i >= 0; i--) {
|
||||
value = (value * 256) + byteArray[i];
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts an integer to a byte array of {length} bytes.
|
||||
*
|
||||
* @param {integer} value
|
||||
* @param {integer} length
|
||||
* @param {string} byteorder - "little" or "big"
|
||||
* @returns {byteArray}
|
||||
*
|
||||
* @example
|
||||
* // returns [5, 255, 109, 1]
|
||||
* Utils.intToByteArray(23985925, 4, "little");
|
||||
*
|
||||
* // returns [1, 109, 255, 5]
|
||||
* Utils.intToByteArray(23985925, 4, "big");
|
||||
*
|
||||
* // returns [0, 0, 0, 0, 1, 109, 255, 5]
|
||||
* Utils.intToByteArray(23985925, 8, "big");
|
||||
*/
|
||||
static intToByteArray(value, length, byteorder) {
|
||||
const arr = new Array(length);
|
||||
if (byteorder === "little") {
|
||||
for (let i = 0; i < length; i++) {
|
||||
arr[i] = value & 0xFF;
|
||||
value = value >>> 8;
|
||||
}
|
||||
} else {
|
||||
for (let i = length - 1; i >= 0; i--) {
|
||||
arr[i] = value & 0xFF;
|
||||
value = value >>> 8;
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a string to an ArrayBuffer.
|
||||
* Treats the string as UTF-8 if any values are over 255.
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
"AES Decrypt",
|
||||
"Blowfish Encrypt",
|
||||
"Blowfish Decrypt",
|
||||
"ChaCha",
|
||||
"DES Encrypt",
|
||||
"DES Decrypt",
|
||||
"Triple DES Encrypt",
|
||||
@@ -249,6 +250,7 @@
|
||||
"To Table",
|
||||
"Reverse",
|
||||
"Sort",
|
||||
"Shuffle",
|
||||
"Unique",
|
||||
"Split",
|
||||
"Filter",
|
||||
@@ -333,7 +335,9 @@
|
||||
"LZString Decompress",
|
||||
"LZString Compress",
|
||||
"LZMA Decompress",
|
||||
"LZMA Compress"
|
||||
"LZMA Compress",
|
||||
"LZ4 Decompress",
|
||||
"LZ4 Compress"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -365,10 +369,13 @@
|
||||
"Compare SSDEEP hashes",
|
||||
"Compare CTPH hashes",
|
||||
"HMAC",
|
||||
"CMAC",
|
||||
"Bcrypt",
|
||||
"Bcrypt compare",
|
||||
"Bcrypt parse",
|
||||
"Scrypt",
|
||||
"NT Hash",
|
||||
"LM Hash",
|
||||
"Fletcher-8 Checksum",
|
||||
"Fletcher-16 Checksum",
|
||||
"Fletcher-32 Checksum",
|
||||
|
||||
@@ -136,7 +136,7 @@ const getFeature = function() {
|
||||
|
||||
fs.writeFileSync(path.join(process.cwd(), "CHANGELOG.md"), changelogData);
|
||||
|
||||
console.log("Written CHANGELOG.md");
|
||||
console.log("Written CHANGELOG.md\nCommit changes and then run `npm version minor`.");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -105,13 +105,17 @@ export function fromHex(data, delim="Auto", byteLen=2) {
|
||||
throw new OperationError("Byte length must be a positive integer");
|
||||
|
||||
if (delim !== "None") {
|
||||
const delimRegex = delim === "Auto" ? /[^a-f\d]|(0x)/gi : Utils.regexRep(delim);
|
||||
data = data.replace(delimRegex, "");
|
||||
const delimRegex = delim === "Auto" ? /[^a-f\d]|0x/gi : Utils.regexRep(delim);
|
||||
data = data.split(delimRegex);
|
||||
} else {
|
||||
data = [data];
|
||||
}
|
||||
|
||||
const output = [];
|
||||
for (let i = 0; i < data.length; i += byteLen) {
|
||||
output.push(parseInt(data.substr(i, byteLen), 16));
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
for (let j = 0; j < data[i].length; j += byteLen) {
|
||||
output.push(parseInt(data[i].substr(j, byteLen), 16));
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -103,3 +103,15 @@ export function hexadecimalSort(a, b) {
|
||||
|
||||
return a.localeCompare(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison operation for sorting by length
|
||||
*
|
||||
* @param {string} a
|
||||
* @param {string} b
|
||||
* @returns {number}
|
||||
*/
|
||||
export function lengthSort(a, b) {
|
||||
return a.length - b.length;
|
||||
}
|
||||
|
||||
|
||||
149
src/core/operations/CMAC.mjs
Normal file
149
src/core/operations/CMAC.mjs
Normal file
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* @author mikecat
|
||||
* @copyright Crown Copyright 2022
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import forge from "node-forge";
|
||||
import { toHexFast } from "../lib/Hex.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* CMAC operation
|
||||
*/
|
||||
class CMAC extends Operation {
|
||||
|
||||
/**
|
||||
* CMAC constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "CMAC";
|
||||
this.module = "Crypto";
|
||||
this.description = "CMAC is a block-cipher based message authentication code algorithm.<br><br>RFC4493 defines AES-CMAC that uses AES encryption with a 128-bit key.<br>NIST SP 800-38B suggests usages of AES with other key lengths and Triple DES.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/CMAC";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Key",
|
||||
"type": "toggleString",
|
||||
"value": "",
|
||||
"toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
|
||||
},
|
||||
{
|
||||
"name": "Encryption algorithm",
|
||||
"type": "option",
|
||||
"value": ["AES", "Triple DES"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const key = Utils.convertToByteString(args[0].string, args[0].option);
|
||||
const algo = args[1];
|
||||
|
||||
const info = (function() {
|
||||
switch (algo) {
|
||||
case "AES":
|
||||
if (key.length !== 16 && key.length !== 24 && key.length !== 32) {
|
||||
throw new OperationError("The key for AES must be either 16, 24, or 32 bytes (currently " + key.length + " bytes)");
|
||||
}
|
||||
return {
|
||||
"algorithm": "AES-ECB",
|
||||
"key": key,
|
||||
"blockSize": 16,
|
||||
"Rb": new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x87]),
|
||||
};
|
||||
case "Triple DES":
|
||||
if (key.length !== 16 && key.length !== 24) {
|
||||
throw new OperationError("The key for Triple DES must be 16 or 24 bytes (currently " + key.length + " bytes)");
|
||||
}
|
||||
return {
|
||||
"algorithm": "3DES-ECB",
|
||||
"key": key.length === 16 ? key + key.substring(0, 8) : key,
|
||||
"blockSize": 8,
|
||||
"Rb": new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0x1b]),
|
||||
};
|
||||
default:
|
||||
throw new OperationError("Undefined encryption algorithm");
|
||||
}
|
||||
})();
|
||||
|
||||
const xor = function(a, b, out) {
|
||||
if (!out) out = new Uint8Array(a.length);
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
out[i] = a[i] ^ b[i];
|
||||
}
|
||||
return out;
|
||||
};
|
||||
|
||||
const leftShift1 = function(a) {
|
||||
const out = new Uint8Array(a.length);
|
||||
let carry = 0;
|
||||
for (let i = a.length - 1; i >= 0; i--) {
|
||||
out[i] = (a[i] << 1) | carry;
|
||||
carry = a[i] >> 7;
|
||||
}
|
||||
return out;
|
||||
};
|
||||
|
||||
const cipher = forge.cipher.createCipher(info.algorithm, info.key);
|
||||
const encrypt = function(a, out) {
|
||||
if (!out) out = new Uint8Array(a.length);
|
||||
cipher.start();
|
||||
cipher.update(forge.util.createBuffer(a));
|
||||
cipher.finish();
|
||||
const cipherText = cipher.output.getBytes();
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
out[i] = cipherText.charCodeAt(i);
|
||||
}
|
||||
return out;
|
||||
};
|
||||
|
||||
const L = encrypt(new Uint8Array(info.blockSize));
|
||||
const K1 = leftShift1(L);
|
||||
if (L[0] & 0x80) xor(K1, info.Rb, K1);
|
||||
const K2 = leftShift1(K1);
|
||||
if (K1[0] & 0x80) xor(K2, info.Rb, K2);
|
||||
|
||||
const n = Math.ceil(input.byteLength / info.blockSize);
|
||||
const lastBlock = (function() {
|
||||
if (n === 0) {
|
||||
const data = new Uint8Array(K2);
|
||||
data[0] ^= 0x80;
|
||||
return data;
|
||||
}
|
||||
const inputLast = new Uint8Array(input, info.blockSize * (n - 1));
|
||||
if (inputLast.length === info.blockSize) {
|
||||
return xor(inputLast, K1, inputLast);
|
||||
} else {
|
||||
const data = new Uint8Array(info.blockSize);
|
||||
data.set(inputLast, 0);
|
||||
data[inputLast.length] = 0x80;
|
||||
return xor(data, K2, data);
|
||||
}
|
||||
})();
|
||||
|
||||
const X = new Uint8Array(info.blockSize);
|
||||
const Y = new Uint8Array(info.blockSize);
|
||||
for (let i = 0; i < n - 1; i++) {
|
||||
xor(X, new Uint8Array(input, info.blockSize * i, info.blockSize), Y);
|
||||
encrypt(Y, X);
|
||||
}
|
||||
xor(lastBlock, X, Y);
|
||||
const T = encrypt(Y);
|
||||
return toHexFast(T);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default CMAC;
|
||||
234
src/core/operations/ChaCha.mjs
Normal file
234
src/core/operations/ChaCha.mjs
Normal file
@@ -0,0 +1,234 @@
|
||||
/**
|
||||
* @author joostrijneveld [joost@joostrijneveld.nl]
|
||||
* @copyright Crown Copyright 2022
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import { toHex } from "../lib/Hex.mjs";
|
||||
|
||||
/**
|
||||
* Computes the ChaCha block function
|
||||
*
|
||||
* @param {byteArray} key
|
||||
* @param {byteArray} nonce
|
||||
* @param {byteArray} counter
|
||||
* @param {integer} rounds
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
function chacha(key, nonce, counter, rounds) {
|
||||
const tau = "expand 16-byte k";
|
||||
const sigma = "expand 32-byte k";
|
||||
|
||||
let state, c;
|
||||
if (key.length === 16) {
|
||||
c = Utils.strToByteArray(tau);
|
||||
state = c.concat(key).concat(key);
|
||||
} else {
|
||||
c = Utils.strToByteArray(sigma);
|
||||
state = c.concat(key);
|
||||
}
|
||||
state = state.concat(counter).concat(nonce);
|
||||
|
||||
const x = Array();
|
||||
for (let i = 0; i < 64; i += 4) {
|
||||
x.push(Utils.byteArrayToInt(state.slice(i, i + 4), "little"));
|
||||
}
|
||||
const a = [...x];
|
||||
|
||||
/**
|
||||
* Macro to compute a 32-bit rotate-left operation
|
||||
*
|
||||
* @param {integer} x
|
||||
* @param {integer} n
|
||||
* @returns {integer}
|
||||
*/
|
||||
function ROL32(x, n) {
|
||||
return ((x << n) & 0xFFFFFFFF) | (x >>> (32 - n));
|
||||
}
|
||||
|
||||
/**
|
||||
* Macro to compute a single ChaCha quarterround operation
|
||||
*
|
||||
* @param {integer} x
|
||||
* @param {integer} a
|
||||
* @param {integer} b
|
||||
* @param {integer} c
|
||||
* @param {integer} d
|
||||
* @returns {integer}
|
||||
*/
|
||||
function quarterround(x, a, b, c, d) {
|
||||
x[a] = ((x[a] + x[b]) & 0xFFFFFFFF); x[d] = ROL32(x[d] ^ x[a], 16);
|
||||
x[c] = ((x[c] + x[d]) & 0xFFFFFFFF); x[b] = ROL32(x[b] ^ x[c], 12);
|
||||
x[a] = ((x[a] + x[b]) & 0xFFFFFFFF); x[d] = ROL32(x[d] ^ x[a], 8);
|
||||
x[c] = ((x[c] + x[d]) & 0xFFFFFFFF); x[b] = ROL32(x[b] ^ x[c], 7);
|
||||
}
|
||||
|
||||
for (let i = 0; i < rounds / 2; i++) {
|
||||
quarterround(x, 0, 4, 8, 12);
|
||||
quarterround(x, 1, 5, 9, 13);
|
||||
quarterround(x, 2, 6, 10, 14);
|
||||
quarterround(x, 3, 7, 11, 15);
|
||||
quarterround(x, 0, 5, 10, 15);
|
||||
quarterround(x, 1, 6, 11, 12);
|
||||
quarterround(x, 2, 7, 8, 13);
|
||||
quarterround(x, 3, 4, 9, 14);
|
||||
}
|
||||
|
||||
for (let i = 0; i < 16; i++) {
|
||||
x[i] = (x[i] + a[i]) & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
let output = Array();
|
||||
for (let i = 0; i < 16; i++) {
|
||||
output = output.concat(Utils.intToByteArray(x[i], 4, "little"));
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* ChaCha operation
|
||||
*/
|
||||
class ChaCha extends Operation {
|
||||
|
||||
/**
|
||||
* ChaCha constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "ChaCha";
|
||||
this.module = "Default";
|
||||
this.description = "ChaCha is a stream cipher designed by Daniel J. Bernstein. It is a variant of the Salsa stream cipher. Several parameterizations exist; 'ChaCha' may refer to the original construction, or to the variant as described in RFC-8439. ChaCha is often used with Poly1305, in the ChaCha20-Poly1305 AEAD construction.<br><br><b>Key:</b> ChaCha uses a key of 16 or 32 bytes (128 or 256 bits).<br><br><b>Nonce:</b> ChaCha uses a nonce of 8 or 12 bytes (64 or 96 bits).<br><br><b>Counter:</b> ChaCha uses a counter of 4 or 8 bytes (32 or 64 bits); together, the nonce and counter must add up to 16 bytes. The counter starts at zero at the start of the keystream, and is incremented at every 64 bytes.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Salsa20#ChaCha_variant";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Key",
|
||||
"type": "toggleString",
|
||||
"value": "",
|
||||
"toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
|
||||
},
|
||||
{
|
||||
"name": "Nonce",
|
||||
"type": "toggleString",
|
||||
"value": "",
|
||||
"toggleValues": ["Hex", "UTF8", "Latin1", "Base64", "Integer"]
|
||||
},
|
||||
{
|
||||
"name": "Counter",
|
||||
"type": "number",
|
||||
"value": 0,
|
||||
"min": 0
|
||||
},
|
||||
{
|
||||
"name": "Rounds",
|
||||
"type": "option",
|
||||
"value": ["20", "12", "8"]
|
||||
},
|
||||
{
|
||||
"name": "Input",
|
||||
"type": "option",
|
||||
"value": ["Hex", "Raw"]
|
||||
},
|
||||
{
|
||||
"name": "Output",
|
||||
"type": "option",
|
||||
"value": ["Raw", "Hex"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const key = Utils.convertToByteArray(args[0].string, args[0].option),
|
||||
nonceType = args[1].option,
|
||||
rounds = parseInt(args[3], 10),
|
||||
inputType = args[4],
|
||||
outputType = args[5];
|
||||
|
||||
if (key.length !== 16 && key.length !== 32) {
|
||||
throw new OperationError(`Invalid key length: ${key.length} bytes.
|
||||
|
||||
ChaCha uses a key of 16 or 32 bytes (128 or 256 bits).`);
|
||||
}
|
||||
|
||||
let counter, nonce, counterLength;
|
||||
if (nonceType === "Integer") {
|
||||
nonce = Utils.intToByteArray(parseInt(args[1].string, 10), 12, "little");
|
||||
counterLength = 4;
|
||||
} else {
|
||||
nonce = Utils.convertToByteArray(args[1].string, args[1].option);
|
||||
if (!(nonce.length === 12 || nonce.length === 8)) {
|
||||
throw new OperationError(`Invalid nonce length: ${nonce.length} bytes.
|
||||
|
||||
ChaCha uses a nonce of 8 or 12 bytes (64 or 96 bits).`);
|
||||
}
|
||||
counterLength = 16 - nonce.length;
|
||||
}
|
||||
counter = Utils.intToByteArray(args[2], counterLength, "little");
|
||||
|
||||
const output = [];
|
||||
input = Utils.convertToByteArray(input, inputType);
|
||||
|
||||
let counterAsInt = Utils.byteArrayToInt(counter, "little");
|
||||
for (let i = 0; i < input.length; i += 64) {
|
||||
counter = Utils.intToByteArray(counterAsInt, counterLength, "little");
|
||||
const stream = chacha(key, nonce, counter, rounds);
|
||||
for (let j = 0; j < 64 && i + j < input.length; j++) {
|
||||
output.push(input[i + j] ^ stream[j]);
|
||||
}
|
||||
counterAsInt++;
|
||||
}
|
||||
|
||||
if (outputType === "Hex") {
|
||||
return toHex(output);
|
||||
} else {
|
||||
return Utils.arrayBufferToStr(output);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight ChaCha
|
||||
*
|
||||
* @param {Object[]} pos
|
||||
* @param {number} pos[].start
|
||||
* @param {number} pos[].end
|
||||
* @param {Object[]} args
|
||||
* @returns {Object[]} pos
|
||||
*/
|
||||
highlight(pos, args) {
|
||||
const inputType = args[4],
|
||||
outputType = args[5];
|
||||
if (inputType === "Raw" && outputType === "Raw") {
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight ChaCha in reverse
|
||||
*
|
||||
* @param {Object[]} pos
|
||||
* @param {number} pos[].start
|
||||
* @param {number} pos[].end
|
||||
* @param {Object[]} args
|
||||
* @returns {Object[]} pos
|
||||
*/
|
||||
highlightReverse(pos, args) {
|
||||
const inputType = args[4],
|
||||
outputType = args[5];
|
||||
if (inputType === "Raw" && outputType === "Raw") {
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ChaCha;
|
||||
@@ -35,10 +35,18 @@ class Fletcher32Checksum extends Operation {
|
||||
run(input, args) {
|
||||
let a = 0,
|
||||
b = 0;
|
||||
input = new Uint8Array(input);
|
||||
if (ArrayBuffer.isView(input)) {
|
||||
input = new DataView(input.buffer, input.byteOffset, input.byteLength);
|
||||
} else {
|
||||
input = new DataView(input);
|
||||
}
|
||||
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
a = (a + input[i]) % 0xffff;
|
||||
for (let i = 0; i < input.byteLength - 1; i += 2) {
|
||||
a = (a + input.getUint16(i, true)) % 0xffff;
|
||||
b = (b + a) % 0xffff;
|
||||
}
|
||||
if (input.byteLength % 2 !== 0) {
|
||||
a = (a + input.getUint8(input.byteLength - 1)) % 0xffff;
|
||||
b = (b + a) % 0xffff;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,10 +35,22 @@ class Fletcher64Checksum extends Operation {
|
||||
run(input, args) {
|
||||
let a = 0,
|
||||
b = 0;
|
||||
input = new Uint8Array(input);
|
||||
if (ArrayBuffer.isView(input)) {
|
||||
input = new DataView(input.buffer, input.byteOffset, input.byteLength);
|
||||
} else {
|
||||
input = new DataView(input);
|
||||
}
|
||||
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
a = (a + input[i]) % 0xffffffff;
|
||||
for (let i = 0; i < input.byteLength - 3; i += 4) {
|
||||
a = (a + input.getUint32(i, true)) % 0xffffffff;
|
||||
b = (b + a) % 0xffffffff;
|
||||
}
|
||||
if (input.byteLength % 4 !== 0) {
|
||||
let lastValue = 0;
|
||||
for (let i = 0; i < input.byteLength % 4; i++) {
|
||||
lastValue = (lastValue << 8) | input.getUint8(input.byteLength - 1 - i);
|
||||
}
|
||||
a = (a + lastValue) % 0xffffffff;
|
||||
b = (b + a) % 0xffffffff;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import {alphabetName, ALPHABET_OPTIONS} from "../lib/Base85.mjs";
|
||||
import {ALPHABET_OPTIONS} from "../lib/Base85.mjs";
|
||||
|
||||
/**
|
||||
* From Base85 operation
|
||||
@@ -37,6 +37,12 @@ class FromBase85 extends Operation {
|
||||
type: "boolean",
|
||||
value: true
|
||||
},
|
||||
{
|
||||
name: "All-zero group char",
|
||||
type: "binaryShortString",
|
||||
value: "z",
|
||||
maxLength: 1
|
||||
}
|
||||
];
|
||||
this.checks = [
|
||||
{
|
||||
@@ -76,8 +82,8 @@ class FromBase85 extends Operation {
|
||||
*/
|
||||
run(input, args) {
|
||||
const alphabet = Utils.expandAlphRange(args[0]).join(""),
|
||||
encoding = alphabetName(alphabet),
|
||||
removeNonAlphChars = args[1],
|
||||
allZeroGroupChar = typeof args[2] === "string" ? args[2].slice(0, 1) : "",
|
||||
result = [];
|
||||
|
||||
if (alphabet.length !== 85 ||
|
||||
@@ -85,14 +91,21 @@ class FromBase85 extends Operation {
|
||||
throw new OperationError("Alphabet must be of length 85");
|
||||
}
|
||||
|
||||
if (allZeroGroupChar && alphabet.includes(allZeroGroupChar)) {
|
||||
throw new OperationError("The all-zero group char cannot appear in the alphabet");
|
||||
}
|
||||
|
||||
// Remove delimiters if present
|
||||
const matches = input.match(/^<~(.+?)~>$/);
|
||||
if (matches !== null) input = matches[1];
|
||||
|
||||
// Remove non-alphabet characters
|
||||
if (removeNonAlphChars) {
|
||||
const re = new RegExp("[^" + alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
|
||||
const re = new RegExp("[^~" + allZeroGroupChar +alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
|
||||
input = input.replace(re, "");
|
||||
// Remove delimiters again if present (incase of non-alphabet characters in front/behind delimiters)
|
||||
const matches = input.match(/^<~(.+?)~>$/);
|
||||
if (matches !== null) input = matches[1];
|
||||
}
|
||||
|
||||
if (input.length === 0) return [];
|
||||
@@ -100,7 +113,7 @@ class FromBase85 extends Operation {
|
||||
let i = 0;
|
||||
let block, blockBytes;
|
||||
while (i < input.length) {
|
||||
if (encoding === "Standard" && input[i] === "z") {
|
||||
if (input[i] === allZeroGroupChar) {
|
||||
result.push(0, 0, 0, 0);
|
||||
i++;
|
||||
} else {
|
||||
@@ -110,7 +123,7 @@ class FromBase85 extends Operation {
|
||||
.split("")
|
||||
.map((chr, idx) => {
|
||||
const digit = alphabet.indexOf(chr);
|
||||
if (digit < 0 || digit > 84) {
|
||||
if ((digit < 0 || digit > 84) && chr !== allZeroGroupChar) {
|
||||
throw `Invalid character '${chr}' at index ${i + idx}`;
|
||||
}
|
||||
return digit;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @author john19696 [john19696@protonmail.com]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
@@ -33,6 +34,9 @@ import BLAKE2b from "./BLAKE2b.mjs";
|
||||
import BLAKE2s from "./BLAKE2s.mjs";
|
||||
import Streebog from "./Streebog.mjs";
|
||||
import GOSTHash from "./GOSTHash.mjs";
|
||||
import LMHash from "./LMHash.mjs";
|
||||
import NTHash from "./NTHash.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* Generate all hashes operation
|
||||
@@ -51,7 +55,75 @@ class GenerateAllHashes extends Operation {
|
||||
this.infoURL = "https://wikipedia.org/wiki/Comparison_of_cryptographic_hash_functions";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
this.args = [
|
||||
{
|
||||
name: "Length (bits)",
|
||||
type: "option",
|
||||
value: [
|
||||
"All", "128", "160", "224", "256", "320", "384", "512"
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Include names",
|
||||
type: "boolean",
|
||||
value: true
|
||||
},
|
||||
];
|
||||
this.hashes = [
|
||||
{name: "MD2", algo: (new MD2()), inputType: "arrayBuffer", params: []},
|
||||
{name: "MD4", algo: (new MD4()), inputType: "arrayBuffer", params: []},
|
||||
{name: "MD5", algo: (new MD5()), inputType: "arrayBuffer", params: []},
|
||||
{name: "MD6", algo: (new MD6()), inputType: "str", params: []},
|
||||
{name: "SHA0", algo: (new SHA0()), inputType: "arrayBuffer", params: []},
|
||||
{name: "SHA1", algo: (new SHA1()), inputType: "arrayBuffer", params: []},
|
||||
{name: "SHA2 224", algo: (new SHA2()), inputType: "arrayBuffer", params: ["224"]},
|
||||
{name: "SHA2 256", algo: (new SHA2()), inputType: "arrayBuffer", params: ["256"]},
|
||||
{name: "SHA2 384", algo: (new SHA2()), inputType: "arrayBuffer", params: ["384"]},
|
||||
{name: "SHA2 512", algo: (new SHA2()), inputType: "arrayBuffer", params: ["512"]},
|
||||
{name: "SHA3 224", algo: (new SHA3()), inputType: "arrayBuffer", params: ["224"]},
|
||||
{name: "SHA3 256", algo: (new SHA3()), inputType: "arrayBuffer", params: ["256"]},
|
||||
{name: "SHA3 384", algo: (new SHA3()), inputType: "arrayBuffer", params: ["384"]},
|
||||
{name: "SHA3 512", algo: (new SHA3()), inputType: "arrayBuffer", params: ["512"]},
|
||||
{name: "Keccak 224", algo: (new Keccak()), inputType: "arrayBuffer", params: ["224"]},
|
||||
{name: "Keccak 256", algo: (new Keccak()), inputType: "arrayBuffer", params: ["256"]},
|
||||
{name: "Keccak 384", algo: (new Keccak()), inputType: "arrayBuffer", params: ["384"]},
|
||||
{name: "Keccak 512", algo: (new Keccak()), inputType: "arrayBuffer", params: ["512"]},
|
||||
{name: "Shake 128", algo: (new Shake()), inputType: "arrayBuffer", params: ["128", 256]},
|
||||
{name: "Shake 256", algo: (new Shake()), inputType: "arrayBuffer", params: ["256", 512]},
|
||||
{name: "RIPEMD-128", algo: (new RIPEMD()), inputType: "arrayBuffer", params: ["128"]},
|
||||
{name: "RIPEMD-160", algo: (new RIPEMD()), inputType: "arrayBuffer", params: ["160"]},
|
||||
{name: "RIPEMD-256", algo: (new RIPEMD()), inputType: "arrayBuffer", params: ["256"]},
|
||||
{name: "RIPEMD-320", algo: (new RIPEMD()), inputType: "arrayBuffer", params: ["320"]},
|
||||
{name: "HAS-160", algo: (new HAS160()), inputType: "arrayBuffer", params: []},
|
||||
{name: "Whirlpool-0", algo: (new Whirlpool()), inputType: "arrayBuffer", params: ["Whirlpool-0"]},
|
||||
{name: "Whirlpool-T", algo: (new Whirlpool()), inputType: "arrayBuffer", params: ["Whirlpool-T"]},
|
||||
{name: "Whirlpool", algo: (new Whirlpool()), inputType: "arrayBuffer", params: ["Whirlpool"]},
|
||||
{name: "BLAKE2b-128", algo: (new BLAKE2b), inputType: "arrayBuffer", params: ["128", "Hex", {string: "", option: "UTF8"}]},
|
||||
{name: "BLAKE2b-160", algo: (new BLAKE2b), inputType: "arrayBuffer", params: ["160", "Hex", {string: "", option: "UTF8"}]},
|
||||
{name: "BLAKE2b-256", algo: (new BLAKE2b), inputType: "arrayBuffer", params: ["256", "Hex", {string: "", option: "UTF8"}]},
|
||||
{name: "BLAKE2b-384", algo: (new BLAKE2b), inputType: "arrayBuffer", params: ["384", "Hex", {string: "", option: "UTF8"}]},
|
||||
{name: "BLAKE2b-512", algo: (new BLAKE2b), inputType: "arrayBuffer", params: ["512", "Hex", {string: "", option: "UTF8"}]},
|
||||
{name: "BLAKE2s-128", algo: (new BLAKE2s), inputType: "arrayBuffer", params: ["128", "Hex", {string: "", option: "UTF8"}]},
|
||||
{name: "BLAKE2s-160", algo: (new BLAKE2s), inputType: "arrayBuffer", params: ["160", "Hex", {string: "", option: "UTF8"}]},
|
||||
{name: "BLAKE2s-256", algo: (new BLAKE2s), inputType: "arrayBuffer", params: ["256", "Hex", {string: "", option: "UTF8"}]},
|
||||
{name: "Streebog-256", algo: (new Streebog), inputType: "arrayBuffer", params: ["256"]},
|
||||
{name: "Streebog-512", algo: (new Streebog), inputType: "arrayBuffer", params: ["512"]},
|
||||
{name: "GOST", algo: (new GOSTHash), inputType: "arrayBuffer", params: ["D-A"]},
|
||||
{name: "LM Hash", algo: (new LMHash), inputType: "str", params: []},
|
||||
{name: "NT Hash", algo: (new NTHash), inputType: "str", params: []},
|
||||
{name: "SSDEEP", algo: (new SSDEEP()), inputType: "str"},
|
||||
{name: "CTPH", algo: (new CTPH()), inputType: "str"}
|
||||
];
|
||||
this.checksums = [
|
||||
{name: "Fletcher-8", algo: (new Fletcher8Checksum), inputType: "byteArray", params: []},
|
||||
{name: "Fletcher-16", algo: (new Fletcher16Checksum), inputType: "byteArray", params: []},
|
||||
{name: "Fletcher-32", algo: (new Fletcher32Checksum), inputType: "byteArray", params: []},
|
||||
{name: "Fletcher-64", algo: (new Fletcher64Checksum), inputType: "byteArray", params: []},
|
||||
{name: "Adler-32", algo: (new Adler32Checksum), inputType: "byteArray", params: []},
|
||||
{name: "CRC-8", algo: (new CRC8Checksum), inputType: "arrayBuffer", params: ["CRC-8"]},
|
||||
{name: "CRC-16", algo: (new CRC16Checksum), inputType: "arrayBuffer", params: []},
|
||||
{name: "CRC-32", algo: (new CRC32Checksum), inputType: "arrayBuffer", params: []}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,63 +132,74 @@ class GenerateAllHashes extends Operation {
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const arrayBuffer = input,
|
||||
str = Utils.arrayBufferToStr(arrayBuffer, false),
|
||||
byteArray = new Uint8Array(arrayBuffer),
|
||||
output = "MD2: " + (new MD2()).run(arrayBuffer, []) +
|
||||
"\nMD4: " + (new MD4()).run(arrayBuffer, []) +
|
||||
"\nMD5: " + (new MD5()).run(arrayBuffer, []) +
|
||||
"\nMD6: " + (new MD6()).run(str, []) +
|
||||
"\nSHA0: " + (new SHA0()).run(arrayBuffer, []) +
|
||||
"\nSHA1: " + (new SHA1()).run(arrayBuffer, []) +
|
||||
"\nSHA2 224: " + (new SHA2()).run(arrayBuffer, ["224"]) +
|
||||
"\nSHA2 256: " + (new SHA2()).run(arrayBuffer, ["256"]) +
|
||||
"\nSHA2 384: " + (new SHA2()).run(arrayBuffer, ["384"]) +
|
||||
"\nSHA2 512: " + (new SHA2()).run(arrayBuffer, ["512"]) +
|
||||
"\nSHA3 224: " + (new SHA3()).run(arrayBuffer, ["224"]) +
|
||||
"\nSHA3 256: " + (new SHA3()).run(arrayBuffer, ["256"]) +
|
||||
"\nSHA3 384: " + (new SHA3()).run(arrayBuffer, ["384"]) +
|
||||
"\nSHA3 512: " + (new SHA3()).run(arrayBuffer, ["512"]) +
|
||||
"\nKeccak 224: " + (new Keccak()).run(arrayBuffer, ["224"]) +
|
||||
"\nKeccak 256: " + (new Keccak()).run(arrayBuffer, ["256"]) +
|
||||
"\nKeccak 384: " + (new Keccak()).run(arrayBuffer, ["384"]) +
|
||||
"\nKeccak 512: " + (new Keccak()).run(arrayBuffer, ["512"]) +
|
||||
"\nShake 128: " + (new Shake()).run(arrayBuffer, ["128", 256]) +
|
||||
"\nShake 256: " + (new Shake()).run(arrayBuffer, ["256", 512]) +
|
||||
"\nRIPEMD-128: " + (new RIPEMD()).run(arrayBuffer, ["128"]) +
|
||||
"\nRIPEMD-160: " + (new RIPEMD()).run(arrayBuffer, ["160"]) +
|
||||
"\nRIPEMD-256: " + (new RIPEMD()).run(arrayBuffer, ["256"]) +
|
||||
"\nRIPEMD-320: " + (new RIPEMD()).run(arrayBuffer, ["320"]) +
|
||||
"\nHAS-160: " + (new HAS160()).run(arrayBuffer, []) +
|
||||
"\nWhirlpool-0: " + (new Whirlpool()).run(arrayBuffer, ["Whirlpool-0"]) +
|
||||
"\nWhirlpool-T: " + (new Whirlpool()).run(arrayBuffer, ["Whirlpool-T"]) +
|
||||
"\nWhirlpool: " + (new Whirlpool()).run(arrayBuffer, ["Whirlpool"]) +
|
||||
"\nBLAKE2b-128: " + (new BLAKE2b).run(arrayBuffer, ["128", "Hex", {string: "", option: "UTF8"}]) +
|
||||
"\nBLAKE2b-160: " + (new BLAKE2b).run(arrayBuffer, ["160", "Hex", {string: "", option: "UTF8"}]) +
|
||||
"\nBLAKE2b-256: " + (new BLAKE2b).run(arrayBuffer, ["256", "Hex", {string: "", option: "UTF8"}]) +
|
||||
"\nBLAKE2b-384: " + (new BLAKE2b).run(arrayBuffer, ["384", "Hex", {string: "", option: "UTF8"}]) +
|
||||
"\nBLAKE2b-512: " + (new BLAKE2b).run(arrayBuffer, ["512", "Hex", {string: "", option: "UTF8"}]) +
|
||||
"\nBLAKE2s-128: " + (new BLAKE2s).run(arrayBuffer, ["128", "Hex", {string: "", option: "UTF8"}]) +
|
||||
"\nBLAKE2s-160: " + (new BLAKE2s).run(arrayBuffer, ["160", "Hex", {string: "", option: "UTF8"}]) +
|
||||
"\nBLAKE2s-256: " + (new BLAKE2s).run(arrayBuffer, ["256", "Hex", {string: "", option: "UTF8"}]) +
|
||||
"\nStreebog-256: " + (new Streebog).run(arrayBuffer, ["256"]) +
|
||||
"\nStreebog-512: " + (new Streebog).run(arrayBuffer, ["512"]) +
|
||||
"\nGOST: " + (new GOSTHash).run(arrayBuffer, ["D-A"]) +
|
||||
"\nSSDEEP: " + (new SSDEEP()).run(str) +
|
||||
"\nCTPH: " + (new CTPH()).run(str) +
|
||||
"\n\nChecksums:" +
|
||||
"\nFletcher-8: " + (new Fletcher8Checksum).run(byteArray, []) +
|
||||
"\nFletcher-16: " + (new Fletcher16Checksum).run(byteArray, []) +
|
||||
"\nFletcher-32: " + (new Fletcher32Checksum).run(byteArray, []) +
|
||||
"\nFletcher-64: " + (new Fletcher64Checksum).run(byteArray, []) +
|
||||
"\nAdler-32: " + (new Adler32Checksum).run(byteArray, []) +
|
||||
"\nCRC-8: " + (new CRC8Checksum).run(arrayBuffer, ["CRC-8"]) +
|
||||
"\nCRC-16: " + (new CRC16Checksum).run(arrayBuffer, []) +
|
||||
"\nCRC-32: " + (new CRC32Checksum).run(arrayBuffer, []);
|
||||
const [length, includeNames] = args;
|
||||
this.inputArrayBuffer = input;
|
||||
this.inputStr = Utils.arrayBufferToStr(input, false);
|
||||
this.inputByteArray = new Uint8Array(input);
|
||||
|
||||
let digest, output = "";
|
||||
// iterate over each of the hashes
|
||||
this.hashes.forEach(hash => {
|
||||
digest = this.executeAlgo(hash.algo, hash.inputType, hash.params || []);
|
||||
output += this.formatDigest(digest, length, includeNames, hash.name);
|
||||
});
|
||||
|
||||
if (length === "All") {
|
||||
output += "\nChecksums:\n";
|
||||
this.checksums.forEach(checksum => {
|
||||
digest = this.executeAlgo(checksum.algo, checksum.inputType, checksum.params || []);
|
||||
output += this.formatDigest(digest, length, includeNames, checksum.name);
|
||||
});
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a hash or checksum algorithm
|
||||
*
|
||||
* @param {Function} algo - The hash or checksum algorithm
|
||||
* @param {string} inputType
|
||||
* @param {Object[]} [params=[]]
|
||||
* @returns {string}
|
||||
*/
|
||||
executeAlgo(algo, inputType, params=[]) {
|
||||
let digest = null;
|
||||
switch (inputType) {
|
||||
case "arrayBuffer":
|
||||
digest = algo.run(this.inputArrayBuffer, params);
|
||||
break;
|
||||
case "str":
|
||||
digest = algo.run(this.inputStr, params);
|
||||
break;
|
||||
case "byteArray":
|
||||
digest = algo.run(this.inputByteArray, params);
|
||||
break;
|
||||
default:
|
||||
throw new OperationError("Unknown hash input type: " + inputType);
|
||||
}
|
||||
|
||||
return digest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the digest depending on user-specified arguments
|
||||
* @param {string} digest
|
||||
* @param {string} length
|
||||
* @param {boolean} includeNames
|
||||
* @param {string} name
|
||||
* @returns {string}
|
||||
*/
|
||||
formatDigest(digest, length, includeNames, name) {
|
||||
if (length !== "All" && (digest.length * 4) !== parseInt(length, 10))
|
||||
return "";
|
||||
|
||||
if (!includeNames)
|
||||
return digest + "\n";
|
||||
|
||||
return `${name}:${" ".repeat(13-name.length)}${digest}\n`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default GenerateAllHashes;
|
||||
|
||||
@@ -44,7 +44,7 @@ class GenerateQRCode extends Operation {
|
||||
{
|
||||
"name": "Margin (num modules)",
|
||||
"type": "number",
|
||||
"value": 2,
|
||||
"value": 4,
|
||||
"min": 0
|
||||
},
|
||||
{
|
||||
|
||||
@@ -26,6 +26,13 @@ class JWTDecode extends Operation {
|
||||
this.inputType = "string";
|
||||
this.outputType = "JSON";
|
||||
this.args = [];
|
||||
this.checks = [
|
||||
{
|
||||
pattern: "^ey([A-Za-z0-9_-]+)\\.ey([A-Za-z0-9_-]+)\\.([A-Za-z0-9_-]+)$",
|
||||
flags: "",
|
||||
args: []
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
41
src/core/operations/LMHash.mjs
Normal file
41
src/core/operations/LMHash.mjs
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2022
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import {smbhash} from "ntlm";
|
||||
|
||||
/**
|
||||
* LM Hash operation
|
||||
*/
|
||||
class LMHash extends Operation {
|
||||
|
||||
/**
|
||||
* LMHash constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "LM Hash";
|
||||
this.module = "Crypto";
|
||||
this.description = "An LM Hash, or LAN Manager Hash, is a deprecated way of storing passwords on old Microsoft operating systems. It is particularly weak and can be cracked in seconds on modern hardware using rainbow tables.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/LAN_Manager#Password_hashing_algorithm";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
return smbhash.lmhash(input);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default LMHash;
|
||||
43
src/core/operations/LZ4Compress.mjs
Normal file
43
src/core/operations/LZ4Compress.mjs
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2022
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import lz4 from "lz4js";
|
||||
|
||||
/**
|
||||
* LZ4 Compress operation
|
||||
*/
|
||||
class LZ4Compress extends Operation {
|
||||
|
||||
/**
|
||||
* LZ4Compress constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "LZ4 Compress";
|
||||
this.module = "Compression";
|
||||
this.description = "LZ4 is a lossless data compression algorithm that is focused on compression and decompression speed. It belongs to the LZ77 family of byte-oriented compression schemes.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/LZ4_(compression_algorithm)";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "ArrayBuffer";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {ArrayBuffer}
|
||||
*/
|
||||
run(input, args) {
|
||||
const inBuf = new Uint8Array(input);
|
||||
const compressed = lz4.compress(inBuf);
|
||||
return compressed.buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default LZ4Compress;
|
||||
43
src/core/operations/LZ4Decompress.mjs
Normal file
43
src/core/operations/LZ4Decompress.mjs
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2022
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import lz4 from "lz4js";
|
||||
|
||||
/**
|
||||
* LZ4 Decompress operation
|
||||
*/
|
||||
class LZ4Decompress extends Operation {
|
||||
|
||||
/**
|
||||
* LZ4Decompress constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "LZ4 Decompress";
|
||||
this.module = "Compression";
|
||||
this.description = "LZ4 is a lossless data compression algorithm that is focused on compression and decompression speed. It belongs to the LZ77 family of byte-oriented compression schemes.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/LZ4_(compression_algorithm)";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "ArrayBuffer";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {ArrayBuffer}
|
||||
*/
|
||||
run(input, args) {
|
||||
const inBuf = new Uint8Array(input);
|
||||
const decompressed = lz4.decompress(inBuf);
|
||||
return decompressed.buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default LZ4Decompress;
|
||||
46
src/core/operations/NTHash.mjs
Normal file
46
src/core/operations/NTHash.mjs
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @author brun0ne [brunonblok@gmail.com]
|
||||
* @copyright Crown Copyright 2022
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
|
||||
import cptable from "codepage";
|
||||
import {runHash} from "../lib/Hash.mjs";
|
||||
|
||||
/**
|
||||
* NT Hash operation
|
||||
*/
|
||||
class NTHash extends Operation {
|
||||
|
||||
/**
|
||||
* NTHash constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "NT Hash";
|
||||
this.module = "Crypto";
|
||||
this.description = "An NT Hash, sometimes referred to as an NTLM hash, is a method of storing passwords on Windows systems. It works by running MD4 on UTF-16LE encoded input. NTLM hashes are considered weak because they can be brute-forced very easily with modern hardware.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/NT_LAN_Manager";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const format = 1200; // UTF-16LE
|
||||
const encoded = cptable.utils.encode(format, input);
|
||||
const hashed = runHash("md4", encoded);
|
||||
|
||||
return hashed.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
export default NTHash;
|
||||
@@ -45,8 +45,8 @@ class ParseASN1HexString extends Operation {
|
||||
*/
|
||||
run(input, args) {
|
||||
const [index, truncateLen] = args;
|
||||
return r.ASN1HEX.dump(input.replace(/\s/g, ""), {
|
||||
"ommitLongOctet": truncateLen
|
||||
return r.ASN1HEX.dump(input.replace(/\s/g, "").toLowerCase(), {
|
||||
"ommit_long_octet": truncateLen
|
||||
}, index);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,23 +57,29 @@ class ParseX509Certificate extends Operation {
|
||||
const cert = new r.X509(),
|
||||
inputFormat = args[0];
|
||||
|
||||
switch (inputFormat) {
|
||||
case "DER Hex":
|
||||
input = input.replace(/\s/g, "");
|
||||
cert.readCertHex(input);
|
||||
break;
|
||||
case "PEM":
|
||||
cert.readCertPEM(input);
|
||||
break;
|
||||
case "Base64":
|
||||
cert.readCertHex(toHex(fromBase64(input, null, "byteArray"), ""));
|
||||
break;
|
||||
case "Raw":
|
||||
cert.readCertHex(toHex(Utils.strToByteArray(input), ""));
|
||||
break;
|
||||
default:
|
||||
throw "Undefined input format";
|
||||
let undefinedInputFormat = false;
|
||||
try {
|
||||
switch (inputFormat) {
|
||||
case "DER Hex":
|
||||
input = input.replace(/\s/g, "").toLowerCase();
|
||||
cert.readCertHex(input);
|
||||
break;
|
||||
case "PEM":
|
||||
cert.readCertPEM(input);
|
||||
break;
|
||||
case "Base64":
|
||||
cert.readCertHex(toHex(fromBase64(input, null, "byteArray"), ""));
|
||||
break;
|
||||
case "Raw":
|
||||
cert.readCertHex(toHex(Utils.strToByteArray(input), ""));
|
||||
break;
|
||||
default:
|
||||
undefinedInputFormat = true;
|
||||
}
|
||||
} catch (e) {
|
||||
throw "Certificate load error (non-certificate input?)";
|
||||
}
|
||||
if (undefinedInputFormat) throw "Undefined input format";
|
||||
|
||||
const sn = cert.getSerialNumberHex(),
|
||||
issuer = cert.getIssuer(),
|
||||
|
||||
@@ -52,8 +52,12 @@ class PseudoRandomNumberGenerator extends Operation {
|
||||
let bytes;
|
||||
|
||||
if (isWorkerEnvironment() && self.crypto) {
|
||||
bytes = self.crypto.getRandomValues(new Uint8Array(numBytes));
|
||||
bytes = Utils.arrayBufferToStr(bytes.buffer);
|
||||
bytes = new ArrayBuffer(numBytes);
|
||||
const CHUNK_SIZE = 65536;
|
||||
for (let i = 0; i < numBytes; i += CHUNK_SIZE) {
|
||||
self.crypto.getRandomValues(new Uint8Array(bytes, i, Math.min(numBytes - i, CHUNK_SIZE)));
|
||||
}
|
||||
bytes = Utils.arrayBufferToStr(bytes);
|
||||
} else {
|
||||
bytes = forge.random.getBytesSync(numBytes);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
import Operation from "../Operation.mjs";
|
||||
import {INFLATE_BUFFER_TYPE} from "../lib/Zlib.mjs";
|
||||
import rawinflate from "zlibjs/bin/rawinflate.min.js";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
const Zlib = rawinflate.Zlib;
|
||||
|
||||
@@ -83,25 +82,6 @@ class RawInflate extends Operation {
|
||||
}),
|
||||
result = new Uint8Array(inflate.decompress());
|
||||
|
||||
// Raw Inflate sometimes messes up and returns nonsense like this:
|
||||
// ]....]....]....]....]....]....]....]....]....]....]....]....]....]...
|
||||
// e.g. Input data of [8b, 1d, dc, 44]
|
||||
// Look for the first two square brackets:
|
||||
if (result.length > 158 && result[0] === 93 && result[5] === 93) {
|
||||
// If the first two square brackets are there, check that the others
|
||||
// are also there. If they are, throw an error. If not, continue.
|
||||
let valid = false;
|
||||
for (let i = 0; i < 155; i += 5) {
|
||||
if (result[i] !== 93) {
|
||||
valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
throw new OperationError("Error: Unable to inflate data");
|
||||
}
|
||||
}
|
||||
// This seems to be the easiest way...
|
||||
return result.buffer;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
|
||||
/**
|
||||
* Reverse operation
|
||||
@@ -26,7 +27,8 @@ class Reverse extends Operation {
|
||||
{
|
||||
"name": "By",
|
||||
"type": "option",
|
||||
"value": ["Character", "Line"]
|
||||
"value": ["Byte", "Character", "Line"],
|
||||
"defaultIndex": 1
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -57,6 +59,24 @@ class Reverse extends Operation {
|
||||
result.push(0x0a);
|
||||
}
|
||||
return result.slice(0, input.length);
|
||||
} else if (args[0] === "Character") {
|
||||
const inputString = Utils.byteArrayToUtf8(input);
|
||||
let result = "";
|
||||
for (let i = inputString.length - 1; i >= 0; i--) {
|
||||
const c = inputString.charCodeAt(i);
|
||||
if (i > 0 && 0xdc00 <= c && c <= 0xdfff) {
|
||||
const c2 = inputString.charCodeAt(i - 1);
|
||||
if (0xd800 <= c2 && c2 <= 0xdbff) {
|
||||
// surrogates
|
||||
result += inputString.charAt(i - 1);
|
||||
result += inputString.charAt(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
result += inputString.charAt(i);
|
||||
}
|
||||
return Utils.strToUtf8ByteArray(result);
|
||||
} else {
|
||||
return input.reverse();
|
||||
}
|
||||
|
||||
78
src/core/operations/Shuffle.mjs
Normal file
78
src/core/operations/Shuffle.mjs
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @author mikecat
|
||||
* @copyright Crown Copyright 2022
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import {INPUT_DELIM_OPTIONS} from "../lib/Delim.mjs";
|
||||
|
||||
/**
|
||||
* Shuffle operation
|
||||
*/
|
||||
class Shuffle extends Operation {
|
||||
|
||||
/**
|
||||
* Shuffle constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Shuffle";
|
||||
this.module = "Default";
|
||||
this.description = "Randomly reorders input elements.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Shuffling";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Delimiter",
|
||||
type: "option",
|
||||
value: INPUT_DELIM_OPTIONS
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const delim = Utils.charRep(args[0]);
|
||||
if (input.length === 0) return input;
|
||||
|
||||
// return a random number in [0, 1)
|
||||
const rng = (typeof crypto) !== "undefined" && crypto.getRandomValues ? (function() {
|
||||
const buf = new Uint32Array(2);
|
||||
return function() {
|
||||
// generate 53-bit random integer: 21 + 32 bits
|
||||
crypto.getRandomValues(buf);
|
||||
const value = (buf[0] >>> (32 - 21)) * ((1 << 30) * 4) + buf[1];
|
||||
return value / ((1 << 23) * (1 << 30));
|
||||
};
|
||||
})() : Math.random;
|
||||
|
||||
// return a random integer in [0, max)
|
||||
const randint = function(max) {
|
||||
return Math.floor(rng() * max);
|
||||
};
|
||||
|
||||
// Split input into shuffleable sections
|
||||
const toShuffle = input.split(delim);
|
||||
|
||||
// shuffle elements
|
||||
for (let i = toShuffle.length - 1; i > 0; i--) {
|
||||
const idx = randint(i + 1);
|
||||
const tmp = toShuffle[idx];
|
||||
toShuffle[idx] = toShuffle[i];
|
||||
toShuffle[i] = tmp;
|
||||
}
|
||||
|
||||
return toShuffle.join(delim);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Shuffle;
|
||||
@@ -7,7 +7,7 @@
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import {INPUT_DELIM_OPTIONS} from "../lib/Delim.mjs";
|
||||
import {caseInsensitiveSort, ipSort, numericSort, hexadecimalSort} from "../lib/Sort.mjs";
|
||||
import {caseInsensitiveSort, ipSort, numericSort, hexadecimalSort, lengthSort} from "../lib/Sort.mjs";
|
||||
|
||||
/**
|
||||
* Sort operation
|
||||
@@ -39,7 +39,7 @@ class Sort extends Operation {
|
||||
{
|
||||
"name": "Order",
|
||||
"type": "option",
|
||||
"value": ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address", "Numeric", "Numeric (hexadecimal)"]
|
||||
"value": ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address", "Numeric", "Numeric (hexadecimal)", "Length"]
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -65,6 +65,8 @@ class Sort extends Operation {
|
||||
sorted = sorted.sort(numericSort);
|
||||
} else if (order === "Numeric (hexadecimal)") {
|
||||
sorted = sorted.sort(hexadecimalSort);
|
||||
} else if (order === "Length") {
|
||||
sorted = sorted.sort(lengthSort);
|
||||
}
|
||||
|
||||
if (sortReverse) sorted.reverse();
|
||||
|
||||
@@ -34,10 +34,50 @@ class Substitute extends Operation {
|
||||
"name": "Ciphertext",
|
||||
"type": "binaryString",
|
||||
"value": "XYZABCDEFGHIJKLMNOPQRSTUVW"
|
||||
},
|
||||
{
|
||||
"name": "Ignore case",
|
||||
"type": "boolean",
|
||||
"value": false
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a single character using the dictionary, if ignoreCase is true then
|
||||
* check in the dictionary for both upper and lower case versions of the character.
|
||||
* In output the input character case is preserved.
|
||||
* @param {string} char
|
||||
* @param {Object} dict
|
||||
* @param {boolean} ignoreCase
|
||||
* @returns {string}
|
||||
*/
|
||||
cipherSingleChar(char, dict, ignoreCase) {
|
||||
if (!ignoreCase)
|
||||
return dict[char] || char;
|
||||
|
||||
const isUpperCase = char === char.toUpperCase();
|
||||
|
||||
// convert using the dictionary keeping the case of the input character
|
||||
|
||||
if (dict[char] !== undefined) {
|
||||
// if the character is in the dictionary return the value with the input case
|
||||
return isUpperCase ? dict[char].toUpperCase() : dict[char].toLowerCase();
|
||||
}
|
||||
|
||||
// check for the other case, if it is in the dictionary return the value with the right case
|
||||
if (isUpperCase) {
|
||||
if (dict[char.toLowerCase()] !== undefined)
|
||||
return dict[char.toLowerCase()].toUpperCase();
|
||||
} else {
|
||||
if (dict[char.toUpperCase()] !== undefined)
|
||||
return dict[char.toUpperCase()].toLowerCase();
|
||||
}
|
||||
|
||||
return char;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
@@ -45,17 +85,23 @@ class Substitute extends Operation {
|
||||
*/
|
||||
run(input, args) {
|
||||
const plaintext = Utils.expandAlphRange([...args[0]]),
|
||||
ciphertext = Utils.expandAlphRange([...args[1]]);
|
||||
let output = "",
|
||||
index = -1;
|
||||
ciphertext = Utils.expandAlphRange([...args[1]]),
|
||||
ignoreCase = args[2];
|
||||
let output = "";
|
||||
|
||||
if (plaintext.length !== ciphertext.length) {
|
||||
output = "Warning: Plaintext and Ciphertext lengths differ\n\n";
|
||||
}
|
||||
|
||||
// create dictionary for conversion
|
||||
const dict = {};
|
||||
for (let i = 0; i < Math.min(ciphertext.length, plaintext.length); i++) {
|
||||
dict[plaintext[i]] = ciphertext[i];
|
||||
}
|
||||
|
||||
// map every letter with the conversion function
|
||||
for (const character of input) {
|
||||
index = plaintext.indexOf(character);
|
||||
output += index > -1 && index < ciphertext.length ? ciphertext[index] : character;
|
||||
output += this.cipherSingleChar(character, dict, ignoreCase);
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
@@ -20,7 +20,7 @@ class ToTable extends Operation {
|
||||
|
||||
this.name = "To Table";
|
||||
this.module = "Default";
|
||||
this.description = "Data can be split on different characters and rendered as an HTML or ASCII table with an optional header row.<br><br>Supports the CSV (Comma Separated Values) file format by default. Change the cell delimiter argument to <code>\\t</code> to support TSV (Tab Separated Values) or <code>|</code> for PSV (Pipe Separated Values).<br><br>You can enter as many delimiters as you like. Each character will be treat as a separate possible delimiter.";
|
||||
this.description = "Data can be split on different characters and rendered as an HTML, ASCII or Markdown table with an optional header row.<br><br>Supports the CSV (Comma Separated Values) file format by default. Change the cell delimiter argument to <code>\\t</code> to support TSV (Tab Separated Values) or <code>|</code> for PSV (Pipe Separated Values).<br><br>You can enter as many delimiters as you like. Each character will be treat as a separate possible delimiter.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Comma-separated_values";
|
||||
this.inputType = "string";
|
||||
this.outputType = "html";
|
||||
@@ -43,7 +43,7 @@ class ToTable extends Operation {
|
||||
{
|
||||
"name": "Format",
|
||||
"type": "option",
|
||||
"value": ["ASCII", "HTML"]
|
||||
"value": ["ASCII", "HTML", "Markdown"]
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -66,6 +66,9 @@ class ToTable extends Operation {
|
||||
case "ASCII":
|
||||
return asciiOutput(tableData);
|
||||
case "HTML":
|
||||
return htmlOutput(tableData);
|
||||
case "Markdown":
|
||||
return markdownOutput(tableData);
|
||||
default:
|
||||
return htmlOutput(tableData);
|
||||
}
|
||||
@@ -183,6 +186,59 @@ class ToTable extends Operation {
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs an array of data as a Markdown table.
|
||||
*
|
||||
* @param {string[][]} tableData
|
||||
* @returns {string}
|
||||
*/
|
||||
function markdownOutput(tableData) {
|
||||
const headerDivider = "-";
|
||||
const verticalBorder = "|";
|
||||
|
||||
let output = "";
|
||||
const longestCells = [];
|
||||
|
||||
// Find longestCells value per column to pad cells equally.
|
||||
tableData.forEach(function(row, index) {
|
||||
row.forEach(function(cell, cellIndex) {
|
||||
if (longestCells[cellIndex] === undefined || cell.length > longestCells[cellIndex]) {
|
||||
longestCells[cellIndex] = cell.length;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Ignoring the checkbox, as current Mardown renderer in CF doesn't handle table without headers
|
||||
const row = tableData.shift();
|
||||
output += outputRow(row, longestCells);
|
||||
let rowOutput = verticalBorder;
|
||||
row.forEach(function(cell, index) {
|
||||
rowOutput += " " + headerDivider + " " + verticalBorder;
|
||||
});
|
||||
output += rowOutput += "\n";
|
||||
|
||||
// Add the rest of the table rows.
|
||||
tableData.forEach(function(row, index) {
|
||||
output += outputRow(row, longestCells);
|
||||
});
|
||||
|
||||
return output;
|
||||
|
||||
/**
|
||||
* Outputs a row of correctly padded cells.
|
||||
*/
|
||||
function outputRow(row, longestCells) {
|
||||
let rowOutput = verticalBorder;
|
||||
row.forEach(function(cell, index) {
|
||||
rowOutput += " " + cell + " ".repeat(longestCells[index] - cell.length) + " " + verticalBorder;
|
||||
});
|
||||
rowOutput += "\n";
|
||||
return rowOutput;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ class TripleDESDecrypt extends Operation {
|
||||
inputType = args[3],
|
||||
outputType = args[4];
|
||||
|
||||
if (key.length !== 24) {
|
||||
if (key.length !== 24 && key.length !== 16) {
|
||||
throw new OperationError(`Invalid key length: ${key.length} bytes
|
||||
|
||||
Triple DES uses a key length of 24 bytes (192 bits).
|
||||
@@ -85,7 +85,8 @@ Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
|
||||
|
||||
input = Utils.convertToByteString(input, inputType);
|
||||
|
||||
const decipher = forge.cipher.createDecipher("3DES-" + mode, key);
|
||||
const decipher = forge.cipher.createDecipher("3DES-" + mode,
|
||||
key.length === 16 ? key + key.substring(0, 8) : key);
|
||||
|
||||
/* Allow for a "no padding" mode */
|
||||
if (noPadding) {
|
||||
|
||||
@@ -69,7 +69,7 @@ class TripleDESEncrypt extends Operation {
|
||||
inputType = args[3],
|
||||
outputType = args[4];
|
||||
|
||||
if (key.length !== 24) {
|
||||
if (key.length !== 24 && key.length !== 16) {
|
||||
throw new OperationError(`Invalid key length: ${key.length} bytes
|
||||
|
||||
Triple DES uses a key length of 24 bytes (192 bits).
|
||||
@@ -84,7 +84,8 @@ Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
|
||||
|
||||
input = Utils.convertToByteString(input, inputType);
|
||||
|
||||
const cipher = forge.cipher.createCipher("3DES-" + mode, key);
|
||||
const cipher = forge.cipher.createCipher("3DES-" + mode,
|
||||
key.length === 16 ? key + key.substring(0, 8) : key);
|
||||
cipher.start({iv: iv});
|
||||
cipher.update(forge.util.createBuffer(input));
|
||||
cipher.finish();
|
||||
|
||||
@@ -79,6 +79,9 @@ class UNIXTimestampToWindowsFiletime extends Operation {
|
||||
flipped += result.charAt(i);
|
||||
flipped += result.charAt(i + 1);
|
||||
}
|
||||
if (result.length % 2 !== 0) {
|
||||
flipped += "0" + result.charAt(0);
|
||||
}
|
||||
result = flipped;
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ class ViewBitPlane extends Operation {
|
||||
* @returns {html}
|
||||
*/
|
||||
present(data) {
|
||||
if (!data.length) return "";
|
||||
if (!data.byteLength) return "";
|
||||
const type = isImage(data);
|
||||
|
||||
return `<img src="data:${type};base64,${toBase64(data)}">`;
|
||||
|
||||
@@ -52,7 +52,10 @@ class WindowsFiletimeToUNIXTimestamp extends Operation {
|
||||
if (format === "Hex (little endian)") {
|
||||
// Swap endianness
|
||||
let result = "";
|
||||
for (let i = input.length - 2; i >= 0; i -= 2) {
|
||||
if (input.length % 2 !== 0) {
|
||||
result += input.charAt(input.length - 1);
|
||||
}
|
||||
for (let i = input.length - input.length % 2 - 2; i >= 0; i -= 2) {
|
||||
result += input.charAt(i);
|
||||
result += input.charAt(i + 1);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ class HTMLIngredient {
|
||||
this.rows = config.rows || false;
|
||||
this.target = config.target;
|
||||
this.defaultIndex = config.defaultIndex || 0;
|
||||
this.maxLength = config.maxLength || null;
|
||||
this.toggleValues = config.toggleValues;
|
||||
this.ingId = this.app.nextIngId();
|
||||
this.id = "ing-" + this.ingId;
|
||||
@@ -63,7 +64,8 @@ class HTMLIngredient {
|
||||
tabindex="${this.tabIndex}"
|
||||
arg-name="${this.name}"
|
||||
value="${this.value}"
|
||||
${this.disabled ? "disabled" : ""}>
|
||||
${this.disabled ? "disabled" : ""}
|
||||
${this.maxLength ? `maxlength="${this.maxLength}"` : ""}>
|
||||
</div>`;
|
||||
break;
|
||||
case "shortString":
|
||||
@@ -78,7 +80,8 @@ class HTMLIngredient {
|
||||
tabindex="${this.tabIndex}"
|
||||
arg-name="${this.name}"
|
||||
value="${this.value}"
|
||||
${this.disabled ? "disabled" : ""}>
|
||||
${this.disabled ? "disabled" : ""}
|
||||
${this.maxLength ? `maxlength="${this.maxLength}"` : ""}>
|
||||
</div>`;
|
||||
break;
|
||||
case "toggleString":
|
||||
@@ -93,7 +96,8 @@ class HTMLIngredient {
|
||||
tabindex="${this.tabIndex}"
|
||||
arg-name="${this.name}"
|
||||
value="${this.value}"
|
||||
${this.disabled ? "disabled" : ""}>
|
||||
${this.disabled ? "disabled" : ""}
|
||||
${this.maxLength ? `maxlength="${this.maxLength}"` : ""}>
|
||||
</div>
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">${this.toggleValues[0]}</button>
|
||||
|
||||
@@ -45,10 +45,10 @@ TestRegister.addApiTests([
|
||||
const result = chef.ADD("sample input", {
|
||||
key: {
|
||||
string: "some key",
|
||||
option: "Hex"
|
||||
option: "utf8"
|
||||
}
|
||||
});
|
||||
assert.equal(result.toString(), "aO[^ZS\u000eW\\^cb");
|
||||
assert.equal(result.toString(), "\xe6\xd0\xda\xd5\x8c\xd0\x85\xe2\xe1\xdf\xe2\xd9");
|
||||
}),
|
||||
|
||||
|
||||
@@ -121,10 +121,10 @@ Tiger-128`;
|
||||
const result = chef.AND("Scot-free", {
|
||||
key: {
|
||||
string: "Raining Cats and Dogs",
|
||||
option: "Hex",
|
||||
option: "utf8",
|
||||
}
|
||||
});
|
||||
assert.strictEqual(result.toString(), "\u0000\"M$(D E");
|
||||
assert.strictEqual(result.toString(), "Raid)fb A");
|
||||
}),
|
||||
|
||||
it("atBash Cipher", () => {
|
||||
@@ -371,10 +371,10 @@ color: white;
|
||||
},
|
||||
salt: {
|
||||
string: "Market",
|
||||
option: "Hex",
|
||||
option: "utf8",
|
||||
},
|
||||
});
|
||||
assert.strictEqual(result.toString(), "7c21a9f5063a4d62fb1050068245c181");
|
||||
assert.strictEqual(result.toString(), "4930d5d200e80f18c96b5550d13c6af8");
|
||||
}),
|
||||
|
||||
it("Derive PBKDF2 Key", () => {
|
||||
|
||||
@@ -30,6 +30,7 @@ import "./tests/ByteRepr.mjs";
|
||||
import "./tests/CartesianProduct.mjs";
|
||||
import "./tests/CetaceanCipherEncode.mjs";
|
||||
import "./tests/CetaceanCipherDecode.mjs";
|
||||
import "./tests/ChaCha.mjs";
|
||||
import "./tests/CharEnc.mjs";
|
||||
import "./tests/ChangeIPFormat.mjs";
|
||||
import "./tests/Charts.mjs";
|
||||
@@ -45,6 +46,7 @@ import "./tests/DateTime.mjs";
|
||||
import "./tests/ExtractEmailAddresses.mjs";
|
||||
import "./tests/Fork.mjs";
|
||||
import "./tests/FromDecimal.mjs";
|
||||
import "./tests/GenerateAllHashes.mjs";
|
||||
import "./tests/Gzip.mjs";
|
||||
import "./tests/Gunzip.mjs";
|
||||
import "./tests/Hash.mjs";
|
||||
@@ -119,9 +121,13 @@ import "./tests/SIGABA.mjs";
|
||||
import "./tests/ELFInfo.mjs";
|
||||
import "./tests/Subsection.mjs";
|
||||
import "./tests/CaesarBoxCipher.mjs";
|
||||
import "./tests/UnescapeString.mjs";
|
||||
import "./tests/LS47.mjs";
|
||||
import "./tests/LZString.mjs";
|
||||
|
||||
import "./tests/NTLM.mjs";
|
||||
import "./tests/Shuffle.mjs";
|
||||
import "./tests/FletcherChecksum.mjs";
|
||||
import "./tests/CMAC.mjs";
|
||||
|
||||
// Cannot test operations that use the File type yet
|
||||
// import "./tests/SplitColourChannels.mjs";
|
||||
|
||||
@@ -16,6 +16,10 @@ DIb:@FD,*)+C]U=@3BN#EcYf8ATD3s@q?d$AftVqCh[NqF<G:8+EV:.+Cf>-FD5W8ARlolDIal(\
|
||||
DId<j@<?3r@:F%a+D58'ATD4$Bl@l3De:,-DJs`8ARoFb/0JMK@qB4^F!,R<AKZ&-DfTqBG%G>u\
|
||||
D.RTpAKYo'+CT/5+Cei#DII?(E,9)oF*2M7/c";
|
||||
|
||||
const allZeroExample = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
|
||||
|
||||
const allZeroOutput = "zz!!*-'\"9eu7#RLhG$k3[W&.oNg'GVB\"(`=52*$$(B+<_pR,UFcb-n-Vr/1iJ-0JP==1c70M3&s#]4?Ykm5X@_(6q'R884cEH9MJ8X:f1+h<)lt#=BSg3>[:ZC?t!MSA7]@cBPD3sCi+'.E,fo>FEMbNG^4U^I!pHnJ:W<)KS>/9Ll%\"IN/`jYOHG]iPa.Q$R$jD4S=Q7DTV8*TUnsrdW2ZetXKAY/Yd(L?['d?O\\@K2_]Y2%o^qmn*`5Ta:aN;TJbg\"GZd*^:jeCE.%f\\,!5gtgiEi8N\\UjQ5OekiqBum-X60nF?)@o_%qPq\"ad`r;HWp";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "To Base85",
|
||||
@@ -45,4 +49,22 @@ TestRegister.addTests([
|
||||
"args": ["!-u", false] }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "To Base85",
|
||||
input: allZeroExample,
|
||||
expectedOutput: allZeroOutput,
|
||||
recipeConfig: [
|
||||
{ "op": "To Base85",
|
||||
"args": ["!-u"] }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "From Base85",
|
||||
input: allZeroOutput,
|
||||
expectedOutput: allZeroExample,
|
||||
recipeConfig: [
|
||||
{ "op": "From Base85",
|
||||
"args": ["!-u", true, "z"] }
|
||||
]
|
||||
},
|
||||
]);
|
||||
|
||||
314
tests/operations/tests/CMAC.mjs
Normal file
314
tests/operations/tests/CMAC.mjs
Normal file
@@ -0,0 +1,314 @@
|
||||
/**
|
||||
* @author mikecat
|
||||
* @copyright Crown Copyright 2022
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
// values in "NIST's CSRC" testcases are taken from here:
|
||||
// https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
"name": "CMAC-AES128 NIST's CSRC Example #1",
|
||||
"input": "",
|
||||
"expectedOutput": "bb1d6929e95937287fa37d129b756746",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "2b7e151628aed2a6abf7158809cf4f3c"}, "AES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-AES128 NIST's CSRC Example #2",
|
||||
"input": "6bc1bee22e409f96e93d7e117393172a",
|
||||
"expectedOutput": "070a16b46b4d4144f79bdd9dd04a287c",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "2b7e151628aed2a6abf7158809cf4f3c"}, "AES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-AES128 NIST's CSRC Example #3",
|
||||
"input": "6bc1bee22e409f96e93d7e117393172aae2d8a57",
|
||||
"expectedOutput": "7d85449ea6ea19c823a7bf78837dfade",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "2b7e151628aed2a6abf7158809cf4f3c"}, "AES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-AES128 NIST's CSRC Example #4",
|
||||
"input": "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
|
||||
"expectedOutput": "51f0bebf7e3b9d92fc49741779363cfe",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "2b7e151628aed2a6abf7158809cf4f3c"}, "AES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-AES192 NIST's CSRC Example #1",
|
||||
"input": "",
|
||||
"expectedOutput": "d17ddf46adaacde531cac483de7a9367",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"}, "AES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-AES192 NIST's CSRC Example #2",
|
||||
"input": "6bc1bee22e409f96e93d7e117393172a",
|
||||
"expectedOutput": "9e99a7bf31e710900662f65e617c5184",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"}, "AES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-AES192 NIST's CSRC Example #3",
|
||||
"input": "6bc1bee22e409f96e93d7e117393172aae2d8a57",
|
||||
"expectedOutput": "3d75c194ed96070444a9fa7ec740ecf8",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"}, "AES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-AES192 NIST's CSRC Example #4",
|
||||
"input": "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
|
||||
"expectedOutput": "a1d5df0eed790f794d77589659f39a11",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"}, "AES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-AES256 NIST's CSRC Example #1",
|
||||
"input": "",
|
||||
"expectedOutput": "028962f61b7bf89efc6b551f4667d983",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"}, "AES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-AES256 NIST's CSRC Example #2",
|
||||
"input": "6bc1bee22e409f96e93d7e117393172a",
|
||||
"expectedOutput": "28a7023f452e8f82bd4bf28d8c37c35c",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"}, "AES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-AES256 NIST's CSRC Example #3",
|
||||
"input": "6bc1bee22e409f96e93d7e117393172aae2d8a57",
|
||||
"expectedOutput": "156727dc0878944a023c1fe03bad6d93",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"}, "AES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-AES256 NIST's CSRC Example #4",
|
||||
"input": "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
|
||||
"expectedOutput": "e1992190549f6ed5696a2c056c315410",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"}, "AES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-TDES (1) NIST's CSRC Sample #1",
|
||||
"input": "",
|
||||
"expectedOutput": "7db0d37df936c550",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "0123456789abcdef23456789abcdef01456789abcdef0123"}, "Triple DES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-TDES (1) NIST's CSRC Sample #2",
|
||||
"input": "6bc1bee22e409f96e93d7e117393172a",
|
||||
"expectedOutput": "30239cf1f52e6609",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "0123456789abcdef23456789abcdef01456789abcdef0123"}, "Triple DES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-TDES (1) NIST's CSRC Sample #3",
|
||||
"input": "6bc1bee22e409f96e93d7e117393172aae2d8a57",
|
||||
"expectedOutput": "6c9f3ee4923f6be2",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "0123456789abcdef23456789abcdef01456789abcdef0123"}, "Triple DES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-TDES (1) NIST's CSRC Sample #4",
|
||||
"input": "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51",
|
||||
"expectedOutput": "99429bd0bf7904e5",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "0123456789abcdef23456789abcdef01456789abcdef0123"}, "Triple DES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-TDES (2) NIST's CSRC Sample #1",
|
||||
"input": "",
|
||||
"expectedOutput": "79ce52a7f786a960",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "0123456789abcdef23456789abcdef010123456789abcdef"}, "Triple DES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-TDES (2) NIST's CSRC Sample #2",
|
||||
"input": "6bc1bee22e409f96e93d7e117393172a",
|
||||
"expectedOutput": "cc18a0b79af2413b",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "0123456789abcdef23456789abcdef010123456789abcdef"}, "Triple DES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-TDES (2) NIST's CSRC Sample #3",
|
||||
"input": "6bc1bee22e409f96e93d7e117393172aae2d8a57",
|
||||
"expectedOutput": "c06d377ecd101969",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "0123456789abcdef23456789abcdef010123456789abcdef"}, "Triple DES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-TDES (2) NIST's CSRC Sample #4",
|
||||
"input": "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51",
|
||||
"expectedOutput": "9cd33580f9b64dfb",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "0123456789abcdef23456789abcdef010123456789abcdef"}, "Triple DES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-AES: invalid key length",
|
||||
"input": "",
|
||||
"expectedOutput": "The key for AES must be either 16, 24, or 32 bytes (currently 20 bytes)",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "00112233445566778899aabbccddeeff01234567"}, "AES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CMAC-TDES: invalid key length",
|
||||
"input": "",
|
||||
"expectedOutput": "The key for Triple DES must be 16 or 24 bytes (currently 20 bytes)",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "CMAC",
|
||||
"args": [{"option": "Hex", "string": "00112233445566778899aabbccddeeff01234567"}, "Triple DES"]
|
||||
},
|
||||
]
|
||||
},
|
||||
]);
|
||||
151
tests/operations/tests/ChaCha.mjs
Normal file
151
tests/operations/tests/ChaCha.mjs
Normal file
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* ChaCha tests.
|
||||
*
|
||||
* @author joostrijneveld [joost@joostrijneveld.nl]
|
||||
* @copyright Crown Copyright 2022
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "ChaCha: no key",
|
||||
input: "",
|
||||
expectedOutput: `Invalid key length: 0 bytes.
|
||||
|
||||
ChaCha uses a key of 16 or 32 bytes (128 or 256 bits).`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ChaCha",
|
||||
"args": [
|
||||
{"option": "Hex", "string": ""},
|
||||
{"option": "Hex", "string": ""},
|
||||
0, "20", "Hex", "Hex",
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ChaCha: no nonce",
|
||||
input: "",
|
||||
expectedOutput: `Invalid nonce length: 0 bytes.
|
||||
|
||||
ChaCha uses a nonce of 8 or 12 bytes (64 or 96 bits).`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ChaCha",
|
||||
"args": [
|
||||
{"option": "Hex", "string": "00000000000000000000000000000000"},
|
||||
{"option": "Hex", "string": ""},
|
||||
0, "20", "Hex", "Hex",
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ChaCha: RFC8439",
|
||||
input: "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.",
|
||||
expectedOutput: "6e 2e 35 9a 25 68 f9 80 41 ba 07 28 dd 0d 69 81 e9 7e 7a ec 1d 43 60 c2 0a 27 af cc fd 9f ae 0b f9 1b 65 c5 52 47 33 ab 8f 59 3d ab cd 62 b3 57 16 39 d6 24 e6 51 52 ab 8f 53 0c 35 9f 08 61 d8 07 ca 0d bf 50 0d 6a 61 56 a3 8e 08 8a 22 b6 5e 52 bc 51 4d 16 cc f8 06 81 8c e9 1a b7 79 37 36 5a f9 0b bf 74 a3 5b e6 b4 0b 8e ed f2 78 5e 42 87 4d",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ChaCha",
|
||||
"args": [
|
||||
{"option": "Hex", "string": "00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10:11:12:13:14:15:16:17:18:19:1a:1b:1c:1d:1e:1f"},
|
||||
{"option": "Hex", "string": "00:00:00:00:00:00:00:4a:00:00:00:00"},
|
||||
1, "20", "Raw", "Hex",
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ChaCha: draft-strombergson-chacha-test-vectors-01 TC7.1",
|
||||
input: "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
|
||||
expectedOutput: "29 56 0d 28 0b 45 28 40 0a 8f 4b 79 53 69 fb 3a 01 10 55 99 e9 f1 ed 58 27 9c fc 9e ce 2d c5 f9 9f 1c 2e 52 c9 82 38 f5 42 a5 c0 a8 81 d8 50 b6 15 d3 ac d9 fb db 02 6e 93 68 56 5d a5 0e 0d 49 dd 5b e8 ef 74 24 8b 3e 25 1d 96 5d 8f cb 21 e7 cf e2 04 d4 00 78 06 fb ee 3c e9 4c 74 bf ba d2 c1 1c 62 1b a0 48 14 7c 5c aa 94 d1 82 cc ff 6f d5 cf 44 ad f9 6e 3d 68 28 1b b4 96 76 af 87 e7",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ChaCha",
|
||||
"args": [
|
||||
{"option": "Hex", "string": "00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff"},
|
||||
{"option": "Hex", "string": "0f 1e 2d 3c 4b 5a 69 78"},
|
||||
0, "8", "Hex", "Hex",
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ChaCha: draft-strombergson-chacha-test-vectors-01 TC7.2",
|
||||
input: "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
|
||||
expectedOutput: "5e dd c2 d9 42 8f ce ee c5 0a 52 a9 64 ea e0 ff b0 4b 2d e0 06 a9 b0 4c ff 36 8f fa 92 11 16 b2 e8 e2 64 ba bd 2e fa 0d e4 3e f2 e3 b6 d0 65 e8 f7 c0 a1 78 37 b0 a4 0e b0 e2 c7 a3 74 2c 87 53 ed e5 f3 f6 d1 9b e5 54 67 5e 50 6a 77 5c 63 f0 94 d4 96 5c 31 93 19 dc d7 50 6f 45 7b 11 7b 84 b1 0b 24 6e 95 6c 2d a8 89 8a 65 6c ee f3 f7 b7 16 45 b1 9f 70 1d b8 44 85 ce 51 21 f0 f6 17 ef",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ChaCha",
|
||||
"args": [
|
||||
{"option": "Hex", "string": "00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff"},
|
||||
{"option": "Hex", "string": "0f 1e 2d 3c 4b 5a 69 78"},
|
||||
0, "12", "Hex", "Hex",
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ChaCha: draft-strombergson-chacha-test-vectors-01 TC7.3",
|
||||
input: "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
|
||||
expectedOutput: "d1 ab f6 30 46 7e b4 f6 7f 1c fb 47 cd 62 6a ae 8a fe db be 4f f8 fc 5f e9 cf ae 30 7e 74 ed 45 1f 14 04 42 5a d2 b5 45 69 d5 f1 81 48 93 99 71 ab b8 fa fc 88 ce 4a c7 fe 1c 3d 1f 7a 1e b7 ca e7 6c a8 7b 61 a9 71 35 41 49 77 60 dd 9a e0 59 35 0c ad 0d ce df aa 80 a8 83 11 9a 1a 6f 98 7f d1 ce 91 fd 8e e0 82 80 34 b4 11 20 0a 97 45 a2 85 55 44 75 d1 2a fc 04 88 7f ef 35 16 d1 2a 2c",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ChaCha",
|
||||
"args": [
|
||||
{"option": "Hex", "string": "00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff"},
|
||||
{"option": "Hex", "string": "0f 1e 2d 3c 4b 5a 69 78"},
|
||||
0, "20", "Hex", "Hex",
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ChaCha: draft-strombergson-chacha-test-vectors-01 TC7.4",
|
||||
input: "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
|
||||
expectedOutput: "db 43 ad 9d 1e 84 2d 12 72 e4 53 0e 27 6b 3f 56 8f 88 59 b3 f7 cf 6d 9d 2c 74 fa 53 80 8c b5 15 7a 8e bf 46 ad 3d cc 4b 6c 7d ad de 13 17 84 b0 12 0e 0e 22 f6 d5 f9 ff a7 40 7d 4a 21 b6 95 d9 c5 dd 30 bf 55 61 2f ab 9b dd 11 89 20 c1 98 16 47 0c 7f 5d cd 42 32 5d bb ed 8c 57 a5 62 81 c1 44 cb 0f 03 e8 1b 30 04 62 4e 06 50 a1 ce 5a fa f9 a7 cd 81 63 f6 db d7 26 02 25 7d d9 6e 47 1e",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ChaCha",
|
||||
"args": [
|
||||
{"option": "Hex", "string": "00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff ff ee dd cc bb aa 99 88 77 66 55 44 33 22 11 00"},
|
||||
{"option": "Hex", "string": "0f 1e 2d 3c 4b 5a 69 78"},
|
||||
0, "8", "Hex", "Hex",
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ChaCha: draft-strombergson-chacha-test-vectors-01 TC7.5",
|
||||
input: "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
|
||||
expectedOutput: "7e d1 2a 3a 63 91 2a e9 41 ba 6d 4c 0d 5e 86 2e 56 8b 0e 55 89 34 69 35 50 5f 06 4b 8c 26 98 db f7 d8 50 66 7d 8e 67 be 63 9f 3b 4f 6a 16 f9 2e 65 ea 80 f6 c7 42 94 45 da 1f c2 c1 b9 36 50 40 e3 2e 50 c4 10 6f 3b 3d a1 ce 7c cb 1e 71 40 b1 53 49 3c 0f 3a d9 a9 bc ff 07 7e c4 59 6f 1d 0f 29 bf 9c ba a5 02 82 0f 73 2a f5 a9 3c 49 ee e3 3d 1c 4f 12 af 3b 42 97 af 91 fe 41 ea 9e 94 a2",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ChaCha",
|
||||
"args": [
|
||||
{"option": "Hex", "string": "00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff ff ee dd cc bb aa 99 88 77 66 55 44 33 22 11 00"},
|
||||
{"option": "Hex", "string": "0f 1e 2d 3c 4b 5a 69 78"},
|
||||
0, "12", "Hex", "Hex",
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "ChaCha: draft-strombergson-chacha-test-vectors-01 TC7.6",
|
||||
input: "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
|
||||
expectedOutput: "9f ad f4 09 c0 08 11 d0 04 31 d6 7e fb d8 8f ba 59 21 8d 5d 67 08 b1 d6 85 86 3f ab bb 0e 96 1e ea 48 0f d6 fb 53 2b fd 49 4b 21 51 01 50 57 42 3a b6 0a 63 fe 4f 55 f7 a2 12 e2 16 7c ca b9 31 fb fd 29 cf 7b c1 d2 79 ed df 25 dd 31 6b b8 84 3d 6e de e0 bd 1e f1 21 d1 2f a1 7c bc 2c 57 4c cc ab 5e 27 51 67 b0 8b d6 86 f8 a0 9d f8 7e c3 ff b3 53 61 b9 4e bf a1 3f ec 0e 48 89 d1 8d a5",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "ChaCha",
|
||||
"args": [
|
||||
{"option": "Hex", "string": "00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff ff ee dd cc bb aa 99 88 77 66 55 44 33 22 11 00"},
|
||||
{"option": "Hex", "string": "0f 1e 2d 3c 4b 5a 69 78"},
|
||||
0, "20", "Hex", "Hex",
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
]);
|
||||
@@ -75,4 +75,34 @@ TestRegister.addTests([
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "LZ4 Compress",
|
||||
input: "The cat sat on the mat.",
|
||||
expectedOutput: "04224d184070df170000805468652063617420736174206f6e20746865206d61742e00000000",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "LZ4 Compress",
|
||||
"args": []
|
||||
},
|
||||
{
|
||||
"op": "To Hex",
|
||||
"args": ["None", 0]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "LZ4 Decompress",
|
||||
input: "04224d184070df170000805468652063617420736174206f6e20746865206d61742e00000000",
|
||||
expectedOutput: "The cat sat on the mat.",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
},
|
||||
{
|
||||
"op": "LZ4 Decompress",
|
||||
"args": []
|
||||
}
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
108
tests/operations/tests/FletcherChecksum.mjs
Normal file
108
tests/operations/tests/FletcherChecksum.mjs
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* @author mikecat
|
||||
* @copyright Crown Copyright 2022
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Fletcher-16 Checksum: abcde",
|
||||
input: "abcde",
|
||||
expectedOutput: "c8f0",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fletcher-16 Checksum",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Fletcher-16 Checksum: abcdef",
|
||||
input: "abcdef",
|
||||
expectedOutput: "2057",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fletcher-16 Checksum",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Fletcher-16 Checksum: abcdefgh",
|
||||
input: "abcdefgh",
|
||||
expectedOutput: "0627",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fletcher-16 Checksum",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Fletcher-32 Checksum: abcde",
|
||||
input: "abcde",
|
||||
expectedOutput: "f04fc729",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fletcher-32 Checksum",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Fletcher-32 Checksum: abcdef",
|
||||
input: "abcdef",
|
||||
expectedOutput: "56502d2a",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fletcher-32 Checksum",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Fletcher-32 Checksum: abcdefgh",
|
||||
input: "abcdefgh",
|
||||
expectedOutput: "ebe19591",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fletcher-32 Checksum",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Fletcher-64 Checksum: abcde",
|
||||
input: "abcde",
|
||||
expectedOutput: "c8c6c527646362c6",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fletcher-64 Checksum",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Fletcher-64 Checksum: abcdef",
|
||||
input: "abcdef",
|
||||
expectedOutput: "c8c72b276463c8c6",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fletcher-64 Checksum",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Fletcher-64 Checksum: abcdefgh",
|
||||
input: "abcdefgh",
|
||||
expectedOutput: "312e2b28cccac8c6",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Fletcher-64 Checksum",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
115
tests/operations/tests/GenerateAllHashes.mjs
Normal file
115
tests/operations/tests/GenerateAllHashes.mjs
Normal file
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* GenerateAllHashes tests.
|
||||
*
|
||||
* @author john19696 [john19696@protonmail.com]
|
||||
* @copyright Crown Copyright 2022
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Full generate all hashes",
|
||||
input: "test",
|
||||
expectedOutput: `MD2: dd34716876364a02d0195e2fb9ae2d1b
|
||||
MD4: db346d691d7acc4dc2625db19f9e3f52
|
||||
MD5: 098f6bcd4621d373cade4e832627b4f6
|
||||
MD6: 93c8a7d0ff132f325138a82b2baa98c12a7c9ac982feb6c5b310a1ca713615bd
|
||||
SHA0: f8d3b312442a67706057aeb45b983221afb4f035
|
||||
SHA1: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
|
||||
SHA2 224: 90a3ed9e32b2aaf4c61c410eb925426119e1a9dc53d4286ade99a809
|
||||
SHA2 256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
|
||||
SHA2 384: 768412320f7b0aa5812fce428dc4706b3cae50e02a64caa16a782249bfe8efc4b7ef1ccb126255d196047dfedf17a0a9
|
||||
SHA2 512: ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff
|
||||
SHA3 224: 3797bf0afbbfca4a7bbba7602a2b552746876517a7f9b7ce2db0ae7b
|
||||
SHA3 256: 36f028580bb02cc8272a9a020f4200e346e276ae664e45ee80745574e2f5ab80
|
||||
SHA3 384: e516dabb23b6e30026863543282780a3ae0dccf05551cf0295178d7ff0f1b41eecb9db3ff219007c4e097260d58621bd
|
||||
SHA3 512: 9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7b710110c0a678288166e7fbe796883a4f2e9b3ca9f484f521d0ce464345cc1aec96779149c14
|
||||
Keccak 224: 3be30a9ff64f34a5861116c5198987ad780165f8366e67aff4760b5e
|
||||
Keccak 256: 9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658
|
||||
Keccak 384: 53d0ba137307d4c2f9b6674c83edbd58b70c0f4340133ed0adc6fba1d2478a6a03b7788229e775d2de8ae8c0759d0527
|
||||
Keccak 512: 1e2e9fc2002b002d75198b7503210c05a1baac4560916a3c6d93bcce3a50d7f00fd395bf1647b9abb8d1afcc9c76c289b0c9383ba386a956da4b38934417789e
|
||||
Shake 128: d3b0aa9cd8b7255622cebc631e867d4093d6f6010191a53973c45fec9b07c774
|
||||
Shake 256: b54ff7255705a71ee2925e4a3e30e41aed489a579d5595e0df13e32e1e4dd202a7c7f68b31d6418d9845eb4d757adda6ab189e1bb340db818e5b3bc725d992fa
|
||||
RIPEMD-128: f1abb5083c9ff8a9dbbca9cd2b11fead
|
||||
RIPEMD-160: 5e52fee47e6b070565f74372468cdc699de89107
|
||||
RIPEMD-256: fe0289110d07daeee9d9500e14c57787d9083f6ba10e6bcb256f86bb4fe7b981
|
||||
RIPEMD-320: 3b0a2e841e589cf583634a5dd265d2b5d497c4cc44b241e34e0f62d03e98c1b9dc72970b9bc20eb5
|
||||
HAS-160: cb15e491eec6e769771d1f811315139c93071084
|
||||
Whirlpool-0: d50ff71342b521974bae166539871922669afcfc7181250ebbae015c317ebb797173a69e7a05afd11099a9f0918159cd5bc88434d3ca44513d7263caea9244fe
|
||||
Whirlpool-T: e6b4aa087751b4428171777f1893ba585404c7e0171787720eba0d8bccd710dc2c42f874c572bfae4cedabf50f2c80bf923805d4e31c504b86ca3bc59265e7dd
|
||||
Whirlpool: b913d5bbb8e461c2c5961cbe0edcdadfd29f068225ceb37da6defcf89849368f8c6c2eb6a4c4ac75775d032a0ecfdfe8550573062b653fe92fc7b8fb3b7be8d6
|
||||
BLAKE2b-128: 44a8995dd50b6657a037a7839304535b
|
||||
BLAKE2b-160: a34fc3b6d2cce8beb3216c2bbb5e55739e8121ed
|
||||
BLAKE2b-256: 928b20366943e2afd11ebc0eae2e53a93bf177a4fcf35bcc64d503704e65e202
|
||||
BLAKE2b-384: 8a84b8666c8fcfb69f2ec41f578d7c85fbdb504ea6510fb05b50fcbf7ed8153c77943bc2da73abb136834e1a0d4f22cb
|
||||
BLAKE2b-512: a71079d42853dea26e453004338670a53814b78137ffbed07603a41d76a483aa9bc33b582f77d30a65e6f29a896c0411f38312e1d66e0bf16386c86a89bea572
|
||||
BLAKE2s-128: e9ddd9926b9dcb382e09be39ba403d2c
|
||||
BLAKE2s-160: d6197dabec2bd6f4ff303b8e519e8f15d42a453d
|
||||
BLAKE2s-256: f308fc02ce9172ad02a7d75800ecfc027109bc67987ea32aba9b8dcc7b10150e
|
||||
Streebog-256: 12a50838191b5504f1e5f2fd078714cf6b592b9d29af99d0b10d8d02881c3857
|
||||
Streebog-512: 7200bf5dea560f0d7960d07fdc8874ad9f3b86ece2e45f5502ae2e176f2c928e0e581152281f5aee818318bed7cbe6aa69999589234723ceb33175598365b5c8
|
||||
GOST: ee67303696d205ddd2b2363e8e01b4b7199a80957d94d7678eaad3fc834c5a27
|
||||
LM Hash: 01FC5A6BE7BC6929AAD3B435B51404EE
|
||||
NT Hash: 0CB6948805F797BF2A82807973B89537
|
||||
SSDEEP: 3:Hn:Hn
|
||||
CTPH: A:E:E
|
||||
|
||||
Checksums:
|
||||
Fletcher-8: 3d
|
||||
Fletcher-16: 5dc1
|
||||
Fletcher-32: 3f5cd9e7
|
||||
Fletcher-64: 7473657474736574
|
||||
Adler-32: 045d01c1
|
||||
CRC-8: b9
|
||||
CRC-16: f82e
|
||||
CRC-32: d87f7e0c
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all hashes",
|
||||
"args": ["All", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Hashes with length 32",
|
||||
input: "test",
|
||||
expectedOutput: `MD2: dd34716876364a02d0195e2fb9ae2d1b
|
||||
MD4: db346d691d7acc4dc2625db19f9e3f52
|
||||
MD5: 098f6bcd4621d373cade4e832627b4f6
|
||||
RIPEMD-128: f1abb5083c9ff8a9dbbca9cd2b11fead
|
||||
BLAKE2b-128: 44a8995dd50b6657a037a7839304535b
|
||||
BLAKE2s-128: e9ddd9926b9dcb382e09be39ba403d2c
|
||||
LM Hash: 01FC5A6BE7BC6929AAD3B435B51404EE
|
||||
NT Hash: 0CB6948805F797BF2A82807973B89537
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all hashes",
|
||||
"args": ["128", true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Hashes without names",
|
||||
input: "test",
|
||||
expectedOutput: `93c8a7d0ff132f325138a82b2baa98c12a7c9ac982feb6c5b310a1ca713615bd
|
||||
9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
|
||||
36f028580bb02cc8272a9a020f4200e346e276ae664e45ee80745574e2f5ab80
|
||||
9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658
|
||||
d3b0aa9cd8b7255622cebc631e867d4093d6f6010191a53973c45fec9b07c774
|
||||
fe0289110d07daeee9d9500e14c57787d9083f6ba10e6bcb256f86bb4fe7b981
|
||||
928b20366943e2afd11ebc0eae2e53a93bf177a4fcf35bcc64d503704e65e202
|
||||
f308fc02ce9172ad02a7d75800ecfc027109bc67987ea32aba9b8dcc7b10150e
|
||||
12a50838191b5504f1e5f2fd078714cf6b592b9d29af99d0b10d8d02881c3857
|
||||
ee67303696d205ddd2b2363e8e01b4b7199a80957d94d7678eaad3fc834c5a27
|
||||
`,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Generate all hashes",
|
||||
"args": ["256", false]
|
||||
}
|
||||
]
|
||||
}
|
||||
]);
|
||||
34
tests/operations/tests/NTLM.mjs
Normal file
34
tests/operations/tests/NTLM.mjs
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* NTLM test.
|
||||
*
|
||||
* @author brun0ne [brunonblok@gmail.com]
|
||||
* @copyright Crown Copyright 2022
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "NT Hash",
|
||||
input: "QWERTYUIOPASDFGHJKLZXCVBNM1234567890!@#$%^&*()_+.,?/",
|
||||
expectedOutput: "C5FA1C40E55734A8E528DBFE21766D23",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "NT Hash",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "LM Hash",
|
||||
input: "QWERTYUIOPASDFGHJKLZXCVBNM1234567890!@#$%^&*()_+.,?/",
|
||||
expectedOutput: "6D9DF16655336CA75A3C13DD18BA8156",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "LM Hash",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
]);
|
||||
54
tests/operations/tests/Shuffle.mjs
Normal file
54
tests/operations/tests/Shuffle.mjs
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @author mikecat
|
||||
* @copyright Crown Copyright 2022
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
"name": "Shuffle empty",
|
||||
"input": "",
|
||||
"expectedOutput": "",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "Shuffle",
|
||||
"args": ["Comma"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Shuffle bytes",
|
||||
"input": "12345678",
|
||||
"expectedOutput": "31 32 33 34 35 36 37 38",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "Shuffle",
|
||||
"args": ["Nothing (separate chars)"]
|
||||
},
|
||||
{
|
||||
"op": "To Hex",
|
||||
"args": ["Space", 0]
|
||||
},
|
||||
{
|
||||
"op": "Sort",
|
||||
"args": ["Space", false, "Alphabetical (case sensitive)"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Shuffle lines",
|
||||
"input": "1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf\n",
|
||||
"expectedOutput": "\n1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf",
|
||||
"recipeConfig": [
|
||||
{
|
||||
"op": "Shuffle",
|
||||
"args": ["Line feed"]
|
||||
},
|
||||
{
|
||||
"op": "Sort",
|
||||
"args": ["Line feed", false, "Alphabetical (case sensitive)"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]);
|
||||
55
tests/operations/tests/UnescapeString.mjs
Normal file
55
tests/operations/tests/UnescapeString.mjs
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* UnescapeString tests.
|
||||
*
|
||||
* @copyright Crown Copyright 2022
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "UnescapeString: escape sequences",
|
||||
input: "\\a\\b\\f\\n\\r\\t\\v\\'\\\"",
|
||||
expectedOutput: String.fromCharCode(0x07, 0x08, 0x0c, 0x0a, 0x0d, 0x09,
|
||||
0x0b, 0x27, 0x22),
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Unescape string",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "UnescapeString: octals",
|
||||
input: "\\0\\01\\012\\1\\12",
|
||||
expectedOutput: String.fromCharCode(0, 1, 10, 1, 10),
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Unescape string",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "UnescapeString: hexadecimals",
|
||||
input: "\\x00\\xAA\\xaa",
|
||||
expectedOutput: String.fromCharCode(0, 170, 170),
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Unescape string",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "UnescapeString: unicode",
|
||||
input: "\\u0061\\u{0062}",
|
||||
expectedOutput: "ab",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Unescape string",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
Reference in New Issue
Block a user