Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6959e2cf01 | ||
|
|
f5fe79326a | ||
|
|
f77633cee9 | ||
|
|
c858970573 | ||
|
|
fb3eceaee0 | ||
|
|
8e37fec8f8 | ||
|
|
ccaabfaee8 | ||
|
|
c431fb30c5 | ||
|
|
1c04848480 | ||
|
|
ca1a0797fb | ||
|
|
7b497181fd | ||
|
|
92767b1078 | ||
|
|
7c66dacc40 | ||
|
|
632277f9bd | ||
|
|
3c23ae03f5 | ||
|
|
8117926ca3 | ||
|
|
31e9d27f1a | ||
|
|
add745551b | ||
|
|
7b8213e1f6 | ||
|
|
6155634d3b |
No files matched your search
@@ -13,6 +13,10 @@ All major and minor version changes will be documented in this file. Details of
|
||||
|
||||
## Details
|
||||
|
||||
### [9.37.0] - 2022-03-29
|
||||
- 'SM4 Encrypt' and 'SM4 Decrypt' operations added [@swesven] | [#1189]
|
||||
- NoPadding options added for CBC and ECB modes in AES, DES and Triple DES Decrypt operations [@swesven] | [#1189]
|
||||
|
||||
### [9.36.0] - 2022-03-29
|
||||
- 'SIGABA' operation added [@hettysymes] | [#934]
|
||||
|
||||
@@ -284,6 +288,7 @@ All major and minor version changes will be documented in this file. Details of
|
||||
|
||||
|
||||
|
||||
[9.37.0]: https://github.com/gchq/CyberChef/releases/tag/v9.37.0
|
||||
[9.36.0]: https://github.com/gchq/CyberChef/releases/tag/v9.36.0
|
||||
[9.35.0]: https://github.com/gchq/CyberChef/releases/tag/v9.35.0
|
||||
[9.34.0]: https://github.com/gchq/CyberChef/releases/tag/v9.34.0
|
||||
@@ -404,6 +409,7 @@ All major and minor version changes will be documented in this file. Details of
|
||||
[@john19696]: https://github.com/john19696
|
||||
[@t-8ch]: https://github.com/t-8ch
|
||||
[@hettysymes]: https://github.com/hettysymes
|
||||
[@swesven]: https://github.com/swesven
|
||||
|
||||
[8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7
|
||||
[9a33498]: https://github.com/gchq/CyberChef/commit/9a33498fed26a8df9c9f35f39a78a174bf50a513
|
||||
@@ -492,6 +498,7 @@ All major and minor version changes will be documented in this file. Details of
|
||||
[#1049]: https://github.com/gchq/CyberChef/pull/1049
|
||||
[#1065]: https://github.com/gchq/CyberChef/pull/1065
|
||||
[#1083]: https://github.com/gchq/CyberChef/pull/1083
|
||||
[#1189]: https://github.com/gchq/CyberChef/pull/1189
|
||||
[#1242]: https://github.com/gchq/CyberChef/pull/1242
|
||||
[#1244]: https://github.com/gchq/CyberChef/pull/1244
|
||||
[#1313]: https://github.com/gchq/CyberChef/pull/1313
|
||||
|
||||
+3
-2
@@ -10,11 +10,12 @@
|
||||
"start_process": true,
|
||||
"server_path": "./node_modules/.bin/chromedriver",
|
||||
"port": 9515,
|
||||
"log_path": false
|
||||
"log_path": "tests/browser/output"
|
||||
},
|
||||
"desiredCapabilities": {
|
||||
"browserName": "chrome"
|
||||
}
|
||||
},
|
||||
"enable_fail_fast": true
|
||||
},
|
||||
|
||||
"dev": {
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "9.36.1",
|
||||
"version": "9.37.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "cyberchef",
|
||||
"version": "9.36.1",
|
||||
"version": "9.37.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "9.36.1",
|
||||
"version": "9.37.2",
|
||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||
"author": "n1474335 <n1474335@gmail.com>",
|
||||
"homepage": "https://gchq.github.io/CyberChef",
|
||||
|
||||
+2
-2
@@ -723,8 +723,8 @@ class Utils {
|
||||
}
|
||||
|
||||
if (removeScriptAndStyle) {
|
||||
htmlStr = recursiveRemove(/<script[^>]*>.*?<\/script>/gi, htmlStr);
|
||||
htmlStr = recursiveRemove(/<style[^>]*>.*?<\/style>/gi, htmlStr);
|
||||
htmlStr = recursiveRemove(/<script[^>]*>.*?<\/script[^>]*>/gi, htmlStr);
|
||||
htmlStr = recursiveRemove(/<style[^>]*>.*?<\/style[^>]*>/gi, htmlStr);
|
||||
}
|
||||
return htmlStr.replace(/<[^>]+>/g, "");
|
||||
}
|
||||
|
||||
@@ -83,6 +83,8 @@
|
||||
"RC2 Decrypt",
|
||||
"RC4",
|
||||
"RC4 Drop",
|
||||
"SM4 Encrypt",
|
||||
"SM4 Decrypt",
|
||||
"ROT13",
|
||||
"ROT47",
|
||||
"XOR",
|
||||
|
||||
@@ -0,0 +1,331 @@
|
||||
/**
|
||||
* Complete implementation of SM4 cipher encryption/decryption with
|
||||
* ECB, CBC, CFB, OFB, CTR block modes.
|
||||
* These modes are specified in IETF draft-ribose-cfrg-sm4-09, see:
|
||||
* https://tools.ietf.org/id/draft-ribose-cfrg-sm4-09.html
|
||||
* for details.
|
||||
*
|
||||
* Follows spec from Cryptography Standardization Technical Comittee:
|
||||
* http://www.gmbz.org.cn/upload/2018-04-04/1522788048733065051.pdf
|
||||
*
|
||||
* @author swesven
|
||||
* @copyright 2021
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/** Number of rounds */
|
||||
const NROUNDS = 32;
|
||||
|
||||
/** block size in bytes */
|
||||
const BLOCKSIZE = 16;
|
||||
|
||||
/** The S box, 256 8-bit values */
|
||||
const Sbox = [
|
||||
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
|
||||
0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
|
||||
0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
|
||||
0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
|
||||
0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
|
||||
0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
|
||||
0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
|
||||
0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
|
||||
0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
|
||||
0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
|
||||
0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
|
||||
0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
|
||||
0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
|
||||
0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
|
||||
0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
|
||||
0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
|
||||
];
|
||||
|
||||
/** "Fixed parameter CK" used in key expansion */
|
||||
const CK = [
|
||||
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
|
||||
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
|
||||
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
|
||||
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
|
||||
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
|
||||
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
|
||||
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
|
||||
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
|
||||
];
|
||||
|
||||
/** "System parameter FK" */
|
||||
const FK = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc];
|
||||
|
||||
/**
|
||||
* Rotating 32-bit shift left
|
||||
*
|
||||
* (Note that although JS integers are stored in doubles and thus have 53 bits,
|
||||
* the JS bitwise operations are 32-bit)
|
||||
*/
|
||||
function ROL(i, n) {
|
||||
return (i << n) | (i >>> (32 - n));
|
||||
}
|
||||
|
||||
/**
|
||||
* Linear transformation L
|
||||
*
|
||||
* @param {integer} b - a 32 bit integer
|
||||
*/
|
||||
function transformL(b) {
|
||||
/* Replace each of the 4 bytes in b with the value at its offset in the Sbox */
|
||||
b = (Sbox[(b >>> 24) & 0xFF] << 24) | (Sbox[(b >>> 16) & 0xFF] << 16) |
|
||||
(Sbox[(b >>> 8) & 0xFF] << 8) | Sbox[b & 0xFF];
|
||||
/* circular rotate and xor */
|
||||
return b ^ ROL(b, 2) ^ ROL(b, 10) ^ ROL(b, 18) ^ ROL(b, 24);
|
||||
}
|
||||
|
||||
/**
|
||||
* Linear transformation L'
|
||||
*
|
||||
* @param {integer} b - a 32 bit integer
|
||||
*/
|
||||
function transformLprime(b) {
|
||||
/* Replace each of the 4 bytes in b with the value at its offset in the Sbox */
|
||||
b = (Sbox[(b >>> 24) & 0xFF] << 24) | (Sbox[(b >>> 16) & 0xFF] << 16) |
|
||||
(Sbox[(b >>> 8) & 0xFF] << 8) | Sbox[b & 0xFF];
|
||||
return b ^ ROL(b, 13) ^ ROL(b, 23); /* circular rotate and XOR */
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the round key
|
||||
*/
|
||||
function initSM4RoundKey(rawkey) {
|
||||
const K = rawkey.map((a, i) => a ^ FK[i]); /* K = rawkey ^ FK */
|
||||
const roundKey = [];
|
||||
for (let i = 0; i < 32; i++)
|
||||
roundKey[i] = K[i + 4] = K[i] ^ transformLprime(K[i + 1] ^ K[i + 2] ^ K[i + 3] ^ CK[i]);
|
||||
return roundKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts/decrypts a single block X (4 32-bit values) with a prepared round key.
|
||||
*
|
||||
* @param {intArray} X - A cleartext block.
|
||||
* @param {intArray} roundKey - The round key from initSMRoundKey for encrypting (reversed for decrypting).
|
||||
* @returns {byteArray} - The cipher text.
|
||||
*/
|
||||
function encryptBlockSM4(X, roundKey) {
|
||||
for (let i = 0; i < NROUNDS; i++)
|
||||
X[i + 4] = X[i] ^ transformL(X[i + 1] ^ X[i + 2] ^ X[i + 3] ^ roundKey[i]);
|
||||
return [X[35], X[34], X[33], X[32]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes 16 bytes from an offset in an array and returns an array of 4 32-bit Big-Endian values.
|
||||
* (DataView won't work portably here as we need Big-Endian)
|
||||
*
|
||||
* @param {byteArray} bArray - the array of bytes
|
||||
* @param {integer} offset - starting offset in the array; 15 bytes must follow it.
|
||||
*/
|
||||
function bytesToInts(bArray, offs=0) {
|
||||
let offset = offs;
|
||||
const A = (bArray[offset] << 24) | (bArray[offset + 1] << 16) | (bArray[offset + 2] << 8) | bArray[offset + 3];
|
||||
offset += 4;
|
||||
const B = (bArray[offset] << 24) | (bArray[offset + 1] << 16) | (bArray[offset + 2] << 8) | bArray[offset + 3];
|
||||
offset += 4;
|
||||
const C = (bArray[offset] << 24) | (bArray[offset + 1] << 16) | (bArray[offset + 2] << 8) | bArray[offset + 3];
|
||||
offset += 4;
|
||||
const D = (bArray[offset] << 24) | (bArray[offset + 1] << 16) | (bArray[offset + 2] << 8) | bArray[offset + 3];
|
||||
return [A, B, C, D];
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverse of bytesToInts above; takes an array of 32-bit integers and turns it into an array of bytes.
|
||||
* Again, Big-Endian order.
|
||||
*/
|
||||
function intsToBytes(ints) {
|
||||
const bArr = [];
|
||||
for (let i = 0; i < ints.length; i++) {
|
||||
bArr.push((ints[i] >> 24) & 0xFF);
|
||||
bArr.push((ints[i] >> 16) & 0xFF);
|
||||
bArr.push((ints[i] >> 8) & 0xFF);
|
||||
bArr.push(ints[i] & 0xFF);
|
||||
}
|
||||
return bArr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt using SM4 using a given block cipher mode.
|
||||
*
|
||||
* @param {byteArray} message - The clear text message; any length under 32 Gb or so.
|
||||
* @param {byteArray} key - The cipher key, 16 bytes.
|
||||
* @param {byteArray} iv - The IV or nonce, 16 bytes (not used with ECB mode)
|
||||
* @param {string} mode - The block cipher mode "CBC", "ECB", "CFB", "OFB", "CTR".
|
||||
* @param {boolean} noPadding - Don't add PKCS#7 padding if set.
|
||||
* @returns {byteArray} - The cipher text.
|
||||
*/
|
||||
export function encryptSM4(message, key, iv, mode="ECB", noPadding=false) {
|
||||
const messageLength = message.length;
|
||||
if (messageLength === 0)
|
||||
return [];
|
||||
const roundKey = initSM4RoundKey(bytesToInts(key, 0));
|
||||
|
||||
/* Pad with PKCS#7 if requested for ECB/CBC else add zeroes (which are sliced off at the end) */
|
||||
let padByte = 0;
|
||||
let nPadding = 16 - (message.length & 0xF);
|
||||
if (mode === "ECB" || mode === "CBC") {
|
||||
if (noPadding) {
|
||||
if (nPadding !== 16)
|
||||
throw new OperationError(`No padding requested in ${mode} mode but input is not a 16-byte multiple.`);
|
||||
nPadding = 0;
|
||||
} else
|
||||
padByte = nPadding;
|
||||
}
|
||||
for (let i = 0; i < nPadding; i++)
|
||||
message.push(padByte);
|
||||
|
||||
const cipherText = [];
|
||||
switch (mode) {
|
||||
case "ECB":
|
||||
for (let i = 0; i < message.length; i += BLOCKSIZE)
|
||||
Array.prototype.push.apply(cipherText, intsToBytes(encryptBlockSM4(bytesToInts(message, i), roundKey)));
|
||||
break;
|
||||
case "CBC":
|
||||
iv = bytesToInts(iv, 0);
|
||||
for (let i = 0; i < message.length; i += BLOCKSIZE) {
|
||||
const block = bytesToInts(message, i);
|
||||
block[0] ^= iv[0]; block[1] ^= iv[1];
|
||||
block[2] ^= iv[2]; block[3] ^= iv[3];
|
||||
iv = encryptBlockSM4(block, roundKey);
|
||||
Array.prototype.push.apply(cipherText, intsToBytes(iv));
|
||||
}
|
||||
break;
|
||||
case "CFB":
|
||||
iv = bytesToInts(iv, 0);
|
||||
for (let i = 0; i < message.length; i += BLOCKSIZE) {
|
||||
iv = encryptBlockSM4(iv, roundKey);
|
||||
const block = bytesToInts(message, i);
|
||||
block[0] ^= iv[0]; block[1] ^= iv[1];
|
||||
block[2] ^= iv[2]; block[3] ^= iv[3];
|
||||
Array.prototype.push.apply(cipherText, intsToBytes(block));
|
||||
iv = block;
|
||||
}
|
||||
break;
|
||||
case "OFB":
|
||||
iv = bytesToInts(iv, 0);
|
||||
for (let i = 0; i < message.length; i += BLOCKSIZE) {
|
||||
iv = encryptBlockSM4(iv, roundKey);
|
||||
const block = bytesToInts(message, i);
|
||||
block[0] ^= iv[0]; block[1] ^= iv[1];
|
||||
block[2] ^= iv[2]; block[3] ^= iv[3];
|
||||
Array.prototype.push.apply(cipherText, intsToBytes(block));
|
||||
}
|
||||
break;
|
||||
case "CTR":
|
||||
iv = bytesToInts(iv, 0);
|
||||
for (let i = 0; i < message.length; i += BLOCKSIZE) {
|
||||
let iv2 = [...iv]; /* containing the IV + counter */
|
||||
iv2[3] += (i >> 4);/* Using a 32 bit counter here. 64 Gb encrypts should be enough for everyone. */
|
||||
iv2 = encryptBlockSM4(iv2, roundKey);
|
||||
const block = bytesToInts(message, i);
|
||||
block[0] ^= iv2[0]; block[1] ^= iv2[1];
|
||||
block[2] ^= iv2[2]; block[3] ^= iv2[3];
|
||||
Array.prototype.push.apply(cipherText, intsToBytes(block));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new OperationError("Invalid block cipher mode: "+mode);
|
||||
}
|
||||
if (mode !== "ECB" && mode !== "CBC")
|
||||
return cipherText.slice(0, messageLength);
|
||||
return cipherText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt using SM4 using a given block cipher mode.
|
||||
*
|
||||
* @param {byteArray} cipherText - The ciphertext
|
||||
* @param {byteArray} key - The cipher key, 16 bytes.
|
||||
* @param {byteArray} iv - The IV or nonce, 16 bytes (not used with ECB mode)
|
||||
* @param {string} mode - The block cipher mode "CBC", "ECB", "CFB", "OFB", "CTR"
|
||||
* @param {boolean] ignorePadding - If true, ignore padding issues in ECB/CBC mode.
|
||||
* @returns {byteArray} - The cipher text.
|
||||
*/
|
||||
export function decryptSM4(cipherText, key, iv, mode="ECB", ignorePadding=false) {
|
||||
const originalLength = cipherText.length;
|
||||
if (originalLength === 0)
|
||||
return [];
|
||||
let roundKey = initSM4RoundKey(bytesToInts(key, 0));
|
||||
|
||||
if (mode === "ECB" || mode === "CBC") {
|
||||
/* Init decryption key */
|
||||
roundKey = roundKey.reverse();
|
||||
if ((originalLength & 0xF) !== 0 && !ignorePadding)
|
||||
throw new OperationError(`With ECB or CBC modes, the input must be divisible into 16 byte blocks. (${cipherText.length & 0xF} bytes extra)`);
|
||||
} else { /* Pad dummy bytes for other modes, chop them off at the end */
|
||||
while ((cipherText.length & 0xF) !== 0)
|
||||
cipherText.push(0);
|
||||
}
|
||||
|
||||
const clearText = [];
|
||||
switch (mode) {
|
||||
case "ECB":
|
||||
for (let i = 0; i < cipherText.length; i += BLOCKSIZE)
|
||||
Array.prototype.push.apply(clearText, intsToBytes(encryptBlockSM4(bytesToInts(cipherText, i), roundKey)));
|
||||
break;
|
||||
case "CBC":
|
||||
iv = bytesToInts(iv, 0);
|
||||
for (let i = 0; i < cipherText.length; i += BLOCKSIZE) {
|
||||
const block = encryptBlockSM4(bytesToInts(cipherText, i), roundKey);
|
||||
block[0] ^= iv[0]; block[1] ^= iv[1];
|
||||
block[2] ^= iv[2]; block[3] ^= iv[3];
|
||||
Array.prototype.push.apply(clearText, intsToBytes(block));
|
||||
iv = bytesToInts(cipherText, i);
|
||||
}
|
||||
break;
|
||||
case "CFB":
|
||||
iv = bytesToInts(iv, 0);
|
||||
for (let i = 0; i < cipherText.length; i += BLOCKSIZE) {
|
||||
iv = encryptBlockSM4(iv, roundKey);
|
||||
const block = bytesToInts(cipherText, i);
|
||||
block[0] ^= iv[0]; block[1] ^= iv[1];
|
||||
block[2] ^= iv[2]; block[3] ^= iv[3];
|
||||
Array.prototype.push.apply(clearText, intsToBytes(block));
|
||||
iv = bytesToInts(cipherText, i);
|
||||
}
|
||||
break;
|
||||
case "OFB":
|
||||
iv = bytesToInts(iv, 0);
|
||||
for (let i = 0; i < cipherText.length; i += BLOCKSIZE) {
|
||||
iv = encryptBlockSM4(iv, roundKey);
|
||||
const block = bytesToInts(cipherText, i);
|
||||
block[0] ^= iv[0]; block[1] ^= iv[1];
|
||||
block[2] ^= iv[2]; block[3] ^= iv[3];
|
||||
Array.prototype.push.apply(clearText, intsToBytes(block));
|
||||
}
|
||||
break;
|
||||
case "CTR":
|
||||
iv = bytesToInts(iv, 0);
|
||||
for (let i = 0; i < cipherText.length; i += BLOCKSIZE) {
|
||||
let iv2 = [...iv]; /* containing the IV + counter */
|
||||
iv2[3] += (i >> 4);/* Using a 32 bit counter here. 64 Gb encrypts should be enough for everyone. */
|
||||
iv2 = encryptBlockSM4(iv2, roundKey);
|
||||
const block = bytesToInts(cipherText, i);
|
||||
block[0] ^= iv2[0]; block[1] ^= iv2[1];
|
||||
block[2] ^= iv2[2]; block[3] ^= iv2[3];
|
||||
Array.prototype.push.apply(clearText, intsToBytes(block));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new OperationError(`Invalid block cipher mode: ${mode}`);
|
||||
}
|
||||
/* Check PKCS#7 padding */
|
||||
if (mode === "ECB" || mode === "CBC") {
|
||||
if (ignorePadding)
|
||||
return clearText;
|
||||
const padByte = clearText[clearText.length - 1];
|
||||
if (padByte > 16)
|
||||
throw new OperationError("Invalid PKCS#7 padding.");
|
||||
for (let i = 0; i < padByte; i++)
|
||||
if (clearText[clearText.length -i - 1] !== padByte)
|
||||
throw new OperationError("Invalid PKCS#7 padding.");
|
||||
return clearText.slice(0, clearText.length - padByte);
|
||||
}
|
||||
return clearText.slice(0, originalLength);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class AESDecrypt extends Operation {
|
||||
|
||||
this.name = "AES Decrypt";
|
||||
this.module = "Ciphers";
|
||||
this.description = "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.<br><br><b>Key:</b> The following algorithms will be used based on the size of the key:<ul><li>16 bytes = AES-128</li><li>24 bytes = AES-192</li><li>32 bytes = AES-256</li></ul><br><br><b>IV:</b> The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used.<br><br><b>GCM Tag:</b> This field is ignored unless 'GCM' mode is used.";
|
||||
this.description = "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.<br><br><b>Key:</b> The following algorithms will be used based on the size of the key:<ul><li>16 bytes = AES-128</li><li>24 bytes = AES-192</li><li>32 bytes = AES-256</li></ul><br><br><b>IV:</b> The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used as a default.<br><br><b>GCM Tag:</b> This field is ignored unless 'GCM' mode is used.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Advanced_Encryption_Standard";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
@@ -66,6 +66,14 @@ class AESDecrypt extends Operation {
|
||||
{
|
||||
name: "ECB",
|
||||
off: [5, 6]
|
||||
},
|
||||
{
|
||||
name: "CBC/NoPadding",
|
||||
off: [5, 6]
|
||||
},
|
||||
{
|
||||
name: "ECB/NoPadding",
|
||||
off: [5, 6]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -104,7 +112,8 @@ class AESDecrypt extends Operation {
|
||||
run(input, args) {
|
||||
const key = Utils.convertToByteString(args[0].string, args[0].option),
|
||||
iv = Utils.convertToByteString(args[1].string, args[1].option),
|
||||
mode = args[2],
|
||||
mode = args[2].substring(0, 3),
|
||||
noPadding = args[2].endsWith("NoPadding"),
|
||||
inputType = args[3],
|
||||
outputType = args[4],
|
||||
gcmTag = Utils.convertToByteString(args[5].string, args[5].option),
|
||||
@@ -122,6 +131,14 @@ The following algorithms will be used based on the size of the key:
|
||||
input = Utils.convertToByteString(input, inputType);
|
||||
|
||||
const decipher = forge.cipher.createDecipher("AES-" + mode, key);
|
||||
|
||||
/* Allow for a "no padding" mode */
|
||||
if (noPadding) {
|
||||
decipher.mode.unpad = function(output, options) {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
decipher.start({
|
||||
iv: iv.length === 0 ? "" : iv,
|
||||
tag: mode === "GCM" ? gcmTag : undefined,
|
||||
|
||||
@@ -22,7 +22,7 @@ class DESDecrypt extends Operation {
|
||||
|
||||
this.name = "DES Decrypt";
|
||||
this.module = "Ciphers";
|
||||
this.description = "DES is a previously dominant algorithm for encryption, and was published as an official U.S. Federal Information Processing Standard (FIPS). It is now considered to be insecure due to its small key size.<br><br><b>Key:</b> DES uses a key length of 8 bytes (64 bits).<br>Triple DES uses a key length of 24 bytes (192 bits).<br><br><b>IV:</b> The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used.";
|
||||
this.description = "DES is a previously dominant algorithm for encryption, and was published as an official U.S. Federal Information Processing Standard (FIPS). It is now considered to be insecure due to its small key size.<br><br><b>Key:</b> DES uses a key length of 8 bytes (64 bits).<br>Triple DES uses a key length of 24 bytes (192 bits).<br><br><b>IV:</b> The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used as a default.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Data_Encryption_Standard";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
@@ -42,7 +42,7 @@ class DESDecrypt extends Operation {
|
||||
{
|
||||
"name": "Mode",
|
||||
"type": "option",
|
||||
"value": ["CBC", "CFB", "OFB", "CTR", "ECB"]
|
||||
"value": ["CBC", "CFB", "OFB", "CTR", "ECB", "CBC/NoPadding", "ECB/NoPadding"]
|
||||
},
|
||||
{
|
||||
"name": "Input",
|
||||
@@ -65,7 +65,9 @@ class DESDecrypt extends Operation {
|
||||
run(input, args) {
|
||||
const key = Utils.convertToByteString(args[0].string, args[0].option),
|
||||
iv = Utils.convertToByteArray(args[1].string, args[1].option),
|
||||
[,, mode, inputType, outputType] = args;
|
||||
mode = args[2].substring(0, 3),
|
||||
noPadding = args[2].endsWith("NoPadding"),
|
||||
[,,, inputType, outputType] = args;
|
||||
|
||||
if (key.length !== 8) {
|
||||
throw new OperationError(`Invalid key length: ${key.length} bytes
|
||||
@@ -83,6 +85,14 @@ Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
|
||||
input = Utils.convertToByteString(input, inputType);
|
||||
|
||||
const decipher = forge.cipher.createDecipher("DES-" + mode, key);
|
||||
|
||||
/* Allow for a "no padding" mode */
|
||||
if (noPadding) {
|
||||
decipher.mode.unpad = function(output, options) {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
decipher.start({iv: iv});
|
||||
decipher.update(forge.util.createBuffer(input));
|
||||
const result = decipher.finish();
|
||||
|
||||
@@ -43,9 +43,9 @@ class RC4Drop extends Operation {
|
||||
"value": ["Latin1", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Hex", "Base64"]
|
||||
},
|
||||
{
|
||||
"name": "Number of bytes to drop",
|
||||
"name": "Number of dwords to drop",
|
||||
"type": "number",
|
||||
"value": 768
|
||||
"value": 192
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @author swesven
|
||||
* @copyright 2021
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import { toHex } from "../lib/Hex.mjs";
|
||||
import { decryptSM4 } from "../lib/SM4.mjs";
|
||||
|
||||
/**
|
||||
* SM4 Decrypt operation
|
||||
*/
|
||||
class SM4Decrypt extends Operation {
|
||||
|
||||
/**
|
||||
* SM4Encrypt constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "SM4 Decrypt";
|
||||
this.module = "Ciphers";
|
||||
this.description = "SM4 is a 128-bit block cipher, currently established as a national standard (GB/T 32907-2016) of China.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/SM4_(cipher)";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Key",
|
||||
"type": "toggleString",
|
||||
"value": "",
|
||||
"toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
|
||||
},
|
||||
{
|
||||
"name": "IV",
|
||||
"type": "toggleString",
|
||||
"value": "",
|
||||
"toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
|
||||
},
|
||||
{
|
||||
"name": "Mode",
|
||||
"type": "option",
|
||||
"value": ["CBC", "CFB", "OFB", "CTR", "ECB", "CBC/NoPadding", "ECB/NoPadding"]
|
||||
},
|
||||
{
|
||||
"name": "Input",
|
||||
"type": "option",
|
||||
"value": ["Raw", "Hex"]
|
||||
},
|
||||
{
|
||||
"name": "Output",
|
||||
"type": "option",
|
||||
"value": ["Hex", "Raw"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const key = Utils.convertToByteArray(args[0].string, args[0].option),
|
||||
iv = Utils.convertToByteArray(args[1].string, args[1].option),
|
||||
[,, mode, inputType, outputType] = args;
|
||||
|
||||
if (key.length !== 16)
|
||||
throw new OperationError(`Invalid key length: ${key.length} bytes
|
||||
|
||||
SM4 uses a key length of 16 bytes (128 bits).`);
|
||||
if (iv.length !== 16 && !mode.startsWith("ECB"))
|
||||
throw new OperationError(`Invalid IV length: ${iv.length} bytes
|
||||
|
||||
SM4 uses an IV length of 16 bytes (128 bits).
|
||||
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
|
||||
|
||||
input = Utils.convertToByteArray(input, inputType);
|
||||
const output = decryptSM4(input, key, iv, mode.substring(0, 3), mode.endsWith("NoPadding"));
|
||||
return outputType === "Hex" ? toHex(output) : Utils.byteArrayToUtf8(output);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default SM4Decrypt;
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @author swesven
|
||||
* @copyright 2021
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import { toHex } from "../lib/Hex.mjs";
|
||||
import { encryptSM4 } from "../lib/SM4.mjs";
|
||||
|
||||
/**
|
||||
* SM4 Encrypt operation
|
||||
*/
|
||||
class SM4Encrypt extends Operation {
|
||||
|
||||
/**
|
||||
* SM4Encrypt constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "SM4 Encrypt";
|
||||
this.module = "Ciphers";
|
||||
this.description = "SM4 is a 128-bit block cipher, currently established as a national standard (GB/T 32907-2016) of China. Multiple block cipher modes are supported. When using CBC or ECB mode, the PKCS#7 padding scheme is used.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/SM4_(cipher)";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Key",
|
||||
"type": "toggleString",
|
||||
"value": "",
|
||||
"toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
|
||||
},
|
||||
{
|
||||
"name": "IV",
|
||||
"type": "toggleString",
|
||||
"value": "",
|
||||
"toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
|
||||
},
|
||||
{
|
||||
"name": "Mode",
|
||||
"type": "option",
|
||||
"value": ["CBC", "CFB", "OFB", "CTR", "ECB"]
|
||||
},
|
||||
{
|
||||
"name": "Input",
|
||||
"type": "option",
|
||||
"value": ["Raw", "Hex"]
|
||||
},
|
||||
{
|
||||
"name": "Output",
|
||||
"type": "option",
|
||||
"value": ["Hex", "Raw"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const key = Utils.convertToByteArray(args[0].string, args[0].option),
|
||||
iv = Utils.convertToByteArray(args[1].string, args[1].option),
|
||||
[,, mode, inputType, outputType] = args;
|
||||
|
||||
if (key.length !== 16)
|
||||
throw new OperationError(`Invalid key length: ${key.length} bytes
|
||||
|
||||
SM4 uses a key length of 16 bytes (128 bits).`);
|
||||
if (iv.length !== 16 && !mode.startsWith("ECB"))
|
||||
throw new OperationError(`Invalid IV length: ${iv.length} bytes
|
||||
|
||||
SM4 uses an IV length of 16 bytes (128 bits).
|
||||
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);
|
||||
|
||||
input = Utils.convertToByteArray(input, inputType);
|
||||
const output = encryptSM4(input, key, iv, mode.substring(0, 3), mode.endsWith("NoPadding"));
|
||||
return outputType === "Hex" ? toHex(output) : Utils.byteArrayToUtf8(output);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default SM4Encrypt;
|
||||
@@ -43,9 +43,9 @@ class ToBase45 extends Operation {
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
if (!input) return "";
|
||||
input = new Uint8Array(input);
|
||||
const alphabet = Utils.expandAlphRange(args[0]);
|
||||
if (!input) return "";
|
||||
|
||||
const res = [];
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ class TripleDESDecrypt extends Operation {
|
||||
|
||||
this.name = "Triple DES Decrypt";
|
||||
this.module = "Ciphers";
|
||||
this.description = "Triple DES applies DES three times to each block to increase key size.<br><br><b>Key:</b> Triple DES uses a key length of 24 bytes (192 bits).<br>DES uses a key length of 8 bytes (64 bits).<br><br><b>IV:</b> The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used.";
|
||||
this.description = "Triple DES applies DES three times to each block to increase key size.<br><br><b>Key:</b> Triple DES uses a key length of 24 bytes (192 bits).<br>DES uses a key length of 8 bytes (64 bits).<br><br><b>IV:</b> The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used as a default.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Triple_DES";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
@@ -42,7 +42,7 @@ class TripleDESDecrypt extends Operation {
|
||||
{
|
||||
"name": "Mode",
|
||||
"type": "option",
|
||||
"value": ["CBC", "CFB", "OFB", "CTR", "ECB"]
|
||||
"value": ["CBC", "CFB", "OFB", "CTR", "ECB", "CBC/NoPadding", "ECB/NoPadding"]
|
||||
},
|
||||
{
|
||||
"name": "Input",
|
||||
@@ -65,7 +65,8 @@ class TripleDESDecrypt extends Operation {
|
||||
run(input, args) {
|
||||
const key = Utils.convertToByteString(args[0].string, args[0].option),
|
||||
iv = Utils.convertToByteArray(args[1].string, args[1].option),
|
||||
mode = args[2],
|
||||
mode = args[2].substring(0, 3),
|
||||
noPadding = args[2].endsWith("NoPadding"),
|
||||
inputType = args[3],
|
||||
outputType = args[4];
|
||||
|
||||
@@ -85,6 +86,14 @@ 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);
|
||||
|
||||
/* Allow for a "no padding" mode */
|
||||
if (noPadding) {
|
||||
decipher.mode.unpad = function(output, options) {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
decipher.start({iv: iv});
|
||||
decipher.update(forge.util.createBuffer(input));
|
||||
const result = decipher.finish();
|
||||
|
||||
+77
-24
@@ -16,7 +16,8 @@ module.exports = {
|
||||
.click("#auto-bake-label");
|
||||
},
|
||||
|
||||
"Sanity check operations": browser => {
|
||||
"Sanity check operations": async browser => {
|
||||
const Images = await import("../samples/Images.mjs");
|
||||
testOp(browser, "A1Z26 Cipher Decode", "20 5 19 20 15 21 20 16 21 20", "testoutput");
|
||||
testOp(browser, "A1Z26 Cipher Encode", "test input", "20 5 19 20 9 14 16 21 20");
|
||||
testOp(browser, "ADD", "test input", "Ê»ÉÊv¿ÄÆËÊ", [{ "option": "Hex", "string": "56" }]);
|
||||
@@ -24,7 +25,7 @@ module.exports = {
|
||||
testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex"]);
|
||||
testOp(browser, "AND", "test input", "4$04 $044", [{ "option": "Hex", "string": "34" }]);
|
||||
testOp(browser, "Add line numbers", "test input", "1 test input");
|
||||
// testOp(browser, "Add Text To Image", "test input", "test_output");
|
||||
testOp(browser, ["From Hex", "Add Text To Image", "To Base64"], Images.PNG_HEX, Images.PNG_CHEF_B64, [[], ["Chef", "Center", "Middle", 0, 0, 16], []]);
|
||||
testOp(browser, "Adler-32 Checksum", "test input", "16160411");
|
||||
testOp(browser, "Affine Cipher Decode", "test input", "rcqr glnsr", [1, 2]);
|
||||
testOp(browser, "Affine Cipher Encode", "test input", "njln rbfpn", [2, 1]);
|
||||
@@ -44,12 +45,12 @@ module.exports = {
|
||||
// testOp(browser, "Bifid Cipher Encode", "test input", "test_output");
|
||||
// testOp(browser, "Bit shift left", "test input", "test_output");
|
||||
// testOp(browser, "Bit shift right", "test input", "test_output");
|
||||
// testOp(browser, "Blowfish Decrypt", "test input", "test_output");
|
||||
// testOp(browser, "Blowfish Encrypt", "test input", "test_output");
|
||||
// testOp(browser, "Blur Image", "test input", "test_output");
|
||||
testOp(browser, "Blowfish Decrypt", "10884e15427dd84ec35204e9c8e921ae", "test_output", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Hex", "Raw"]);
|
||||
testOp(browser, "Blowfish Encrypt", "test input", "f0fadbd1d90d774f714248cf26b96410", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Raw", "Hex"]);
|
||||
testOp(browser, ["From Hex", "Blur Image", "To Base64"], Images.PNG_HEX, Images.PNG_BLUR_B64);
|
||||
// testOp(browser, "Bombe", "test input", "test_output");
|
||||
// testOp(browser, "Bzip2 Compress", "test input", "test_output");
|
||||
// testOp(browser, "Bzip2 Decompress", "test input", "test_output");
|
||||
testOp(browser, ["Bzip2 Compress", "To Hex"], "test input", "42 5a 68 39 31 41 59 26 53 59 cf 96 82 1d 00 00 03 91 80 40 00 02 21 4e 00 20 00 21 90 c2 10 c0 88 33 92 8e df 17 72 45 38 50 90 cf 96 82 1d");
|
||||
testOp(browser, ["From Hex", "Bzip2 Decompress"], "425a68393141592653597b0884b7000003038000008200ce00200021a647a4218013709517c5dc914e14241ec2212dc0", "test_output", [[], [true]]);
|
||||
// testOp(browser, "CRC-16 Checksum", "test input", "test_output");
|
||||
// testOp(browser, "CRC-32 Checksum", "test input", "test_output");
|
||||
// testOp(browser, "CRC-8 Checksum", "test input", "test_output");
|
||||
@@ -69,10 +70,10 @@ module.exports = {
|
||||
// testOp(browser, "Comment", "test input", "test_output");
|
||||
// testOp(browser, "Compare CTPH hashes", "test input", "test_output");
|
||||
// testOp(browser, "Compare SSDEEP hashes", "test input", "test_output");
|
||||
// testOp(browser, "Conditional Jump", "test input", "test_output");
|
||||
// /testOp(browser, "Conditional Jump", "test input", "test_output");
|
||||
// testOp(browser, "Contain Image", "test input", "test_output");
|
||||
// testOp(browser, "Convert area", "test input", "test_output");
|
||||
// testOp(browser, "Convert co-ordinate format", "test input", "test_output");
|
||||
// /testOp(browser, "Convert co-ordinate format", "test input", "test_output");
|
||||
// testOp(browser, "Convert data units", "test input", "test_output");
|
||||
// testOp(browser, "Convert distance", "test input", "test_output");
|
||||
// testOp(browser, "Convert Image Format", "test input", "test_output");
|
||||
@@ -197,10 +198,12 @@ module.exports = {
|
||||
// testOp(browser, "MD4", "test input", "test_output");
|
||||
// testOp(browser, "MD5", "test input", "test_output");
|
||||
// testOp(browser, "MD6", "test input", "test_output");
|
||||
// testOp(browser, "Magic", "test input", "test_output");
|
||||
testOpHtml(browser, "Magic", "dGVzdF9vdXRwdXQ=", "tr:nth-of-type(1) th:nth-of-type(2)", "Result snippet");
|
||||
testOpHtml(browser, "Magic", "dGVzdF9vdXRwdXQ=", "tr:nth-of-type(2) td:nth-of-type(2)", "test_output");
|
||||
testOpHtml(browser, "Magic", "dGVzdF9vdXRwdXQ=", "tr:nth-of-type(2) td:nth-of-type(1)", /Base64/);
|
||||
// testOp(browser, "Mean", "test input", "test_output");
|
||||
// testOp(browser, "Median", "test input", "test_output");
|
||||
// testOp(browser, "Merge", "test input", "test_output");
|
||||
// testOp(browser, "Median", "test input", "test_output");`
|
||||
// testOp(browser, "Merge", "test input", "test_output");`
|
||||
// testOp(browser, "Microsoft Script Decoder", "test input", "test_output");
|
||||
// testOp(browser, "Multiple Bombe", "test input", "test_output");
|
||||
// testOp(browser, "Multiply", "test input", "test_output");
|
||||
@@ -372,23 +375,36 @@ module.exports = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the current recipe and tests a new operation.
|
||||
/** @function
|
||||
* Clears the current recipe and bakes a new operation.
|
||||
*
|
||||
* @param {string} opName
|
||||
* @param {Browser} browser
|
||||
* @param {Browser} browser - Nightwatch client
|
||||
* @param {string|Array<string>} opName - name of operation to be tested, array for multiple ops
|
||||
* @param {string} input - input text for test
|
||||
* @param {Array<string>|Array<Array<string>>} args - aarguments, nested if multiple ops
|
||||
*/
|
||||
function testOp(browser, opName, input, output, args=[]) {
|
||||
function bakeOp(browser, opName, input, args=[]) {
|
||||
let recipeConfig;
|
||||
|
||||
const recipeConfig = JSON.stringify([{
|
||||
"op": opName,
|
||||
"args": args
|
||||
}]);
|
||||
if (typeof(opName) === "string") {
|
||||
recipeConfig = JSON.stringify([{
|
||||
"op": opName,
|
||||
"args": args
|
||||
}]);
|
||||
} else if (opName instanceof Array) {
|
||||
recipeConfig = JSON.stringify(
|
||||
opName.map((op, i) => {
|
||||
return {
|
||||
op: op,
|
||||
args: args.length ? args[i] : []
|
||||
};
|
||||
})
|
||||
);
|
||||
} else {
|
||||
throw new Error("Invalid operation type. Must be string or array of strings. Received: " + typeof(opName));
|
||||
}
|
||||
|
||||
browser
|
||||
.perform(function() {
|
||||
console.log(opName);
|
||||
})
|
||||
.useCss()
|
||||
.click("#clr-recipe")
|
||||
.click("#clr-io")
|
||||
@@ -396,6 +412,9 @@ function testOp(browser, opName, input, output, args=[]) {
|
||||
.expect.element("#input-text").to.have.property("value").that.equals("");
|
||||
|
||||
browser
|
||||
.perform(function() {
|
||||
console.log(`Current test: ${opName}`);
|
||||
})
|
||||
.urlHash("recipe=" + recipeConfig)
|
||||
.setValue("#input-text", input)
|
||||
.waitForElementPresent("#rec-list li.operation")
|
||||
@@ -408,6 +427,20 @@ function testOp(browser, opName, input, output, args=[]) {
|
||||
.pause(100)
|
||||
.waitForElementPresent("#stale-indicator.hidden", 5000)
|
||||
.waitForElementNotVisible("#output-loader", 5000);
|
||||
}
|
||||
|
||||
/** @function
|
||||
* Clears the current recipe and tests a new operation.
|
||||
*
|
||||
* @param {Browser} browser - Nightwatch client
|
||||
* @param {string|Array<string>} opName - name of operation to be tested, array for multiple ops
|
||||
* @param {string} input - input text
|
||||
* @param {string} output - expected output
|
||||
* @param {Array<string>|Array<Array<string>>} args - arguments, nested if multiple ops
|
||||
*/
|
||||
function testOp(browser, opName, input, output, args=[]) {
|
||||
|
||||
bakeOp(browser, opName, input, args);
|
||||
|
||||
if (typeof output === "string") {
|
||||
browser.expect.element("#output-text").to.have.property("value").that.equals(output);
|
||||
@@ -415,3 +448,23 @@ function testOp(browser, opName, input, output, args=[]) {
|
||||
browser.expect.element("#output-text").to.have.property("value").that.matches(output);
|
||||
}
|
||||
}
|
||||
|
||||
/** @function
|
||||
* Clears the current recipe and tests a new operation.
|
||||
*
|
||||
* @param {Browser} browser - Nightwatch client
|
||||
* @param {string|Array<string>} opName - name of operation to be tested array for multiple ops
|
||||
* @param {string} input - input text
|
||||
* @param {string} cssSelector - CSS selector for HTML output
|
||||
* @param {string} output - expected output
|
||||
* @param {Array<string>|Array<Array<string>>} args - arguments, nested if multiple ops
|
||||
*/
|
||||
function testOpHtml(browser, opName, input, cssSelector, output, args=[]) {
|
||||
bakeOp(browser, opName, input, args);
|
||||
|
||||
if (typeof output === "string") {
|
||||
browser.expect.element("#output-html " + cssSelector).text.that.equals(output);
|
||||
} else if (output instanceof RegExp) {
|
||||
browser.expect.element("#output-html " + cssSelector).text.that.matches(output);
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ TestRegister.addApiTests([
|
||||
assert.strictEqual(result[0].module, "Ciphers");
|
||||
assert.strictEqual(result[0].inputType, "string");
|
||||
assert.strictEqual(result[0].outputType, "string");
|
||||
assert.strictEqual(result[0].description, "Triple DES applies DES three times to each block to increase key size.<br><br><b>Key:</b> Triple DES uses a key length of 24 bytes (192 bits).<br>DES uses a key length of 8 bytes (64 bits).<br><br><b>IV:</b> The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used.");
|
||||
assert.strictEqual(result[0].description, "Triple DES applies DES three times to each block to increase key size.<br><br><b>Key:</b> Triple DES uses a key length of 24 bytes (192 bits).<br>DES uses a key length of 8 bytes (64 bits).<br><br><b>IV:</b> The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used as a default.");
|
||||
assert.strictEqual(result[0].args.length, 5);
|
||||
}),
|
||||
|
||||
|
||||
@@ -816,7 +816,7 @@ pCGTErs=
|
||||
it("RC4 Drop", () => {
|
||||
assert.strictEqual(
|
||||
chef.RC4Drop("Go Out On a Limb", {passphrase: {string: "Under Your Nose", option: "UTF8"}, inputFormat: "UTF8", outputFormat: "Hex"}).toString(),
|
||||
"8fa5f2751d34476a0c857439f43816cf");
|
||||
"b85cb1c4ed6bed8f260ab92829bba942");
|
||||
}),
|
||||
|
||||
it("Regular Expression", () => {
|
||||
|
||||
@@ -75,6 +75,7 @@ import "./tests/SeqUtils.mjs";
|
||||
import "./tests/SetDifference.mjs";
|
||||
import "./tests/SetIntersection.mjs";
|
||||
import "./tests/SetUnion.mjs";
|
||||
import "./tests/SM4.mjs";
|
||||
import "./tests/StrUtils.mjs";
|
||||
import "./tests/SymmetricDifference.mjs";
|
||||
import "./tests/TextEncodingBruteForce.mjs";
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
import { GIF_ANIMATED_HEX, PNG_HEX, JPG_B64, EXIF_JPG_HEX, NO_EXIF_JPG_HEX } from "../samples/Images.mjs";
|
||||
import { GIF_ANIMATED_HEX, PNG_HEX, JPG_B64, EXIF_JPG_HEX, NO_EXIF_JPG_HEX } from "../../samples/Images.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
import { JPG_RAW } from "../samples/Images.mjs";
|
||||
import { JPG_RAW } from "../../samples/Images.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
import {ASCII_TEXT, UTF8_TEXT, ALL_BYTES} from "../samples/Ciphers.mjs";
|
||||
import {ASCII_TEXT, UTF8_TEXT, ALL_BYTES} from "../../samples/Ciphers.mjs";
|
||||
|
||||
// RSA-1024
|
||||
const ALICE_PRIVATE = `-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
import {ASCII_TEXT, UTF8_TEXT, ALL_BYTES} from "../samples/Ciphers.mjs";
|
||||
import {ASCII_TEXT, UTF8_TEXT, ALL_BYTES} from "../../samples/Ciphers.mjs";
|
||||
|
||||
const PEM_PRIV_2048 = `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAwfaUOpUEutKyU3wkCv6kYunz4MqxzSuTSckRz1IxwZtwIiqq
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
/**
|
||||
* SM4 crypto tests.
|
||||
*
|
||||
* Test data used from IETF draft-ribose-cfrg-sm4-09, see:
|
||||
* https://tools.ietf.org/id/draft-ribose-cfrg-sm4-09.html
|
||||
*
|
||||
* @author swesven
|
||||
* @copyright 2021
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
/* Cleartexts */
|
||||
const TWO_BLOCK_PLAIN = "aa aa aa aa bb bb bb bb cc cc cc cc dd dd dd dd ee ee ee ee ff ff ff ff aa aa aa aa bb bb bb bb";
|
||||
const FOUR_BLOCK_PLAIN = "aa aa aa aa aa aa aa aa bb bb bb bb bb bb bb bb cc cc cc cc cc cc cc cc dd dd dd dd dd dd dd dd ee ee ee ee ee ee ee ee ff ff ff ff ff ff ff ff aa aa aa aa aa aa aa aa bb bb bb bb bb bb bb bb";
|
||||
/* Keys */
|
||||
const KEY_1 = "01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10";
|
||||
const KEY_2 = "fe dc ba 98 76 54 32 10 01 23 45 67 89 ab cd ef";
|
||||
/* IV */
|
||||
const IV = "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f";
|
||||
/* Ciphertexts */
|
||||
const ECB_1 = "5e c8 14 3d e5 09 cf f7 b5 17 9f 8f 47 4b 86 19 2f 1d 30 5a 7f b1 7d f9 85 f8 1c 84 82 19 23 04";
|
||||
const ECB_2 = "c5 87 68 97 e4 a5 9b bb a7 2a 10 c8 38 72 24 5b 12 dd 90 bc 2d 20 06 92 b5 29 a4 15 5a c9 e6 00";
|
||||
/* With PKCS#7 padding */
|
||||
const ECB_1P ="5e c8 14 3d e5 09 cf f7 b5 17 9f 8f 47 4b 86 19 2f 1d 30 5a 7f b1 7d f9 85 f8 1c 84 82 19 23 04 00 2a 8a 4e fa 86 3c ca d0 24 ac 03 00 bb 40 d2";
|
||||
const ECB_2P= "c5 87 68 97 e4 a5 9b bb a7 2a 10 c8 38 72 24 5b 12 dd 90 bc 2d 20 06 92 b5 29 a4 15 5a c9 e6 00 a2 51 49 20 93 f8 f6 42 89 b7 8d 6e 8a 28 b1 c6";
|
||||
const CBC_1 = "78 eb b1 1c c4 0b 0a 48 31 2a ae b2 04 02 44 cb 4c b7 01 69 51 90 92 26 97 9b 0d 15 dc 6a 8f 6d";
|
||||
const CBC_2 = "0d 3a 6d dc 2d 21 c6 98 85 72 15 58 7b 7b b5 9a 91 f2 c1 47 91 1a 41 44 66 5e 1f a1 d4 0b ae 38";
|
||||
const OFB_1 = "ac 32 36 cb 86 1d d3 16 e6 41 3b 4e 3c 75 24 b7 1d 01 ac a2 48 7c a5 82 cb f5 46 3e 66 98 53 9b";
|
||||
const OFB_2 = "5d cc cd 25 a8 4b a1 65 60 d7 f2 65 88 70 68 49 33 fa 16 bd 5c d9 c8 56 ca ca a1 e1 01 89 7a 97";
|
||||
const CFB_1 = "ac 32 36 cb 86 1d d3 16 e6 41 3b 4e 3c 75 24 b7 69 d4 c5 4e d4 33 b9 a0 34 60 09 be b3 7b 2b 3f";
|
||||
const CFB_2 = "5d cc cd 25 a8 4b a1 65 60 d7 f2 65 88 70 68 49 0d 9b 86 ff 20 c3 bf e1 15 ff a0 2c a6 19 2c c5";
|
||||
const CTR_1 = "ac 32 36 cb 97 0c c2 07 91 36 4c 39 5a 13 42 d1 a3 cb c1 87 8c 6f 30 cd 07 4c ce 38 5c dd 70 c7 f2 34 bc 0e 24 c1 19 80 fd 12 86 31 0c e3 7b 92 6e 02 fc d0 fa a0 ba f3 8b 29 33 85 1d 82 45 14";
|
||||
const CTR_2 = "5d cc cd 25 b9 5a b0 74 17 a0 85 12 ee 16 0e 2f 8f 66 15 21 cb ba b4 4c c8 71 38 44 5b c2 9e 5c 0a e0 29 72 05 d6 27 04 17 3b 21 23 9b 88 7f 6c 8c b5 b8 00 91 7a 24 88 28 4b de 9e 16 ea 29 06";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "SM4 Encrypt: ECB 1, No padding",
|
||||
input: TWO_BLOCK_PLAIN,
|
||||
expectedOutput: ECB_1,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Encrypt",
|
||||
"args": [{string: KEY_1, option: "Hex"}, {string: "", option: "Hex"}, "ECB/NoPadding", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Encrypt: ECB 2, No padding",
|
||||
input: TWO_BLOCK_PLAIN,
|
||||
expectedOutput: ECB_2,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Encrypt",
|
||||
"args": [{string: KEY_2, option: "Hex"}, {string: "", option: "Hex"}, "ECB/NoPadding", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Encrypt: ECB 1, With padding",
|
||||
input: TWO_BLOCK_PLAIN,
|
||||
expectedOutput: ECB_1P,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Encrypt",
|
||||
"args": [{string: KEY_1, option: "Hex"}, {string: "", option: "Hex"}, "ECB", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Encrypt: ECB 2, With padding",
|
||||
input: TWO_BLOCK_PLAIN,
|
||||
expectedOutput: ECB_2P,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Encrypt",
|
||||
"args": [{string: KEY_2, option: "Hex"}, {string: "", option: "Hex"}, "ECB", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Encrypt: CBC 1",
|
||||
input: TWO_BLOCK_PLAIN,
|
||||
expectedOutput: CBC_1,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Encrypt",
|
||||
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "CBC/NoPadding", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Encrypt: CBC 2",
|
||||
input: TWO_BLOCK_PLAIN,
|
||||
expectedOutput: CBC_2,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Encrypt",
|
||||
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "CBC/NoPadding", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Encrypt: OFB1",
|
||||
input: TWO_BLOCK_PLAIN,
|
||||
expectedOutput: OFB_1,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Encrypt",
|
||||
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "OFB", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Encrypt: OFB2",
|
||||
input: TWO_BLOCK_PLAIN,
|
||||
expectedOutput: OFB_2,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Encrypt",
|
||||
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "OFB", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Encrypt: CFB1",
|
||||
input: TWO_BLOCK_PLAIN,
|
||||
expectedOutput: CFB_1,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Encrypt",
|
||||
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "CFB", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Encrypt: CFB2",
|
||||
input: TWO_BLOCK_PLAIN,
|
||||
expectedOutput: CFB_2,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Encrypt",
|
||||
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "CFB", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Encrypt: CTR1",
|
||||
input: FOUR_BLOCK_PLAIN,
|
||||
expectedOutput: CTR_1,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Encrypt",
|
||||
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "CTR", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Encrypt: CTR1",
|
||||
input: FOUR_BLOCK_PLAIN,
|
||||
expectedOutput: CTR_2,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Encrypt",
|
||||
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "CTR", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Decrypt: ECB 1",
|
||||
input: ECB_1,
|
||||
expectedOutput: TWO_BLOCK_PLAIN,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Decrypt",
|
||||
"args": [{string: KEY_1, option: "Hex"}, {string: "", option: "Hex"}, "ECB/NoPadding", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Decrypt: ECB 2",
|
||||
input: ECB_2,
|
||||
expectedOutput: TWO_BLOCK_PLAIN,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Decrypt",
|
||||
"args": [{string: KEY_2, option: "Hex"}, {string: "", option: "Hex"}, "ECB/NoPadding", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Decrypt: CBC 1",
|
||||
input: CBC_1,
|
||||
expectedOutput: TWO_BLOCK_PLAIN,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Decrypt",
|
||||
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "CBC/NoPadding", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Decrypt: CBC 2",
|
||||
input: CBC_2,
|
||||
expectedOutput: TWO_BLOCK_PLAIN,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Decrypt",
|
||||
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "CBC/NoPadding", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Decrypt: OFB1",
|
||||
input: TWO_BLOCK_PLAIN,
|
||||
expectedOutput: OFB_1,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Decrypt",
|
||||
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "OFB", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Decrypt: OFB2",
|
||||
input: OFB_2,
|
||||
expectedOutput: TWO_BLOCK_PLAIN,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Decrypt",
|
||||
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "OFB", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Decrypt: CFB1",
|
||||
input: CFB_1,
|
||||
expectedOutput: TWO_BLOCK_PLAIN,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Decrypt",
|
||||
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "CFB", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Decrypt: CFB2",
|
||||
input: CFB_2,
|
||||
expectedOutput: TWO_BLOCK_PLAIN,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Decrypt",
|
||||
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "CFB", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Decrypt: CTR1",
|
||||
input: CTR_1,
|
||||
expectedOutput: FOUR_BLOCK_PLAIN,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Decrypt",
|
||||
"args": [{string: KEY_1, option: "Hex"}, {string: IV, option: "Hex"}, "CTR", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "SM4 Decrypt: CTR1",
|
||||
input: CTR_2,
|
||||
expectedOutput: FOUR_BLOCK_PLAIN,
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "SM4 Decrypt",
|
||||
"args": [{string: KEY_2, option: "Hex"}, {string: IV, option: "Hex"}, "CTR", "Hex", "Hex"]
|
||||
}
|
||||
]
|
||||
},
|
||||
]);
|
||||
File renamed without changes.
@@ -18,6 +18,18 @@ export const GIF_ANIMATED_HEX = "4749463839610f000f00b30b00424242ffe700ffef00ffc
|
||||
*/
|
||||
export const PNG_HEX = "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000006624b474400ff00ff00ffa0bda793000000097048597300000dd700000dd70142289b78000005184944415458c3c5575d6c145514feeeccecccacdbddb6e096a5dbcdb6d06d80d06090466d6953454ab52ad0a65589840ac1d02a313c989af062820fa66210130d9a68b0363c34610135690b188b7183c13f44506c8115ba535ab6ddd2617f667f66ae0fb41596ddee2eadf13c4de69e7bcf77cff9cecf25b83f613b3b3b975b2c96f25028c47a3c9e1f5a5a5a7e05a0016000d0c9ef9442d23448a60edeb973a769c78e1d077272721a65594620106000505996bf1a1f1f3f67369bebc2e1f0ef6bd7aedd0a409d2d00e2743a1f2929296915046199a66901007aa3d1580600131313da24000000a594124288aaaab72a2b2bed1d1d1d8f8ba2386fc3860d9f25f3c84c0088cbe56a2d2c2cdc4708d12552880770a7288a3228088215003c1ecfd68d1b377e9e488f4b66dde974aeb2dbed498da71251146d538ed1b4e4746092dddee170b4300ca3c32c251c0edfd8bc79f3d164de4e0680110461794a02119292c482202c387efcf86f3d3d3d7b13814816024a2955e62a8b4451b4abaafad8e485d5743ca005028153699c4dd30c83140a857e4c9409c900a0bbbbfbc368343a34a3754a693a1c58b76eddf2dadada5d89002705b07bf7eee13367ce3cab284aff6c482808425e6767e70bc9ea0033d3e6c6c6c65fd6ac5953a1695a3453c3a150c84d295529a59aa669914cd3705adc6eb7926eaca74455d5605555d5c3030303f59224bd525f5f7f30992e87ff40344d5328a5caa64d9bbe4ca5cbe07f1666ae522dae40a5dd8ed30941c8e5727d63341a9f8a5f181a1ac2f0f07022029e02109d2b00bae2e26207cbb2f72cf03c8f9c9c9c441c580c804dc70b330258b6c020beb87ac9abecb59f8b087377b4f4f30a68b6de482549a29224ddb5168bc51cd5d5d54ff6f5f575cfa69633edeb971c78e2d195db055e77cfb6a2eaadb816e5b59ffafb19a7d3095555e3ab64341a8d96f6f6f6fe755f247c69d542abd9c0bd3c70f90a628c30fd5f56542c5c550fc3837600406e6e2eca9e2e433837fcefc0c8b2e079fe7b9fcfe7aba9a9296613c52f55084acc864a027013b28c828a2d30e805bcbe670fac4b5740f5a9285b18c6a0db4da8c180fdc6fdb035d850c555a174a4148410b85cae7293c97442a7d395363434347775757d91b6075a2a6c45d66ce18369258685de644659d96af45ff80345f9f908c932821313c4eff7639b6d1b06838358242c82d96c86288abe582ce6e6797e052184701c9797910796e61976b10c991fff7f7b5313b6373541d5340426d36f747414e5c67294679503a1e90634e6f57adbac56ebb14020f0e9a14387decf84038c8e232b53b45888dc6dec63636389d290c9caca5a3d09a6a2a6a6a628130054d33092a2c52272bbe4515996113f16288ab2c86432bd01001cc72db5582caf651202eaf5473e7e80d7af270409d9cb320c0c66331ca5a5602c1624180d492412392bcbf2db46a3f1394992f665c481b77a2f9f78e719476b5e16ff2e00d31dae8524cb30e8f560390ee72e5e243d7d7d34168bc16030a87575752ccbb20400a2d1e8b7478e1c390ce0f0fd5442fae6d7039f343d643956345f5fcbf1fafd00b219868145afc78d4b97101a1b833a32426d361bcdcfcf87cd6663a7a6649ee70725497a6faede86e4c2c993cf171716eee5753aeb9d0b7f5ebfae5df67a99b86164e8e6cd9badcdcdcdc7d27ae5a6a3f45147c7794dd30e2e59bcf896c0f3851ccbe602c0a8df4fc783413269d8130c06f79d3e7d7a4b5b5bdbd9b45b77c60304c3f0df75752db31714acf8dbe7cbbee2f5fafd7efff9f6f6f6b357af5e8d647ade3fa1780bad734c65970000000049454e44ae426082";
|
||||
|
||||
/**
|
||||
* The CyberChef logo with 'chef'
|
||||
* 32x32
|
||||
*/
|
||||
export const PNG_CHEF_B64 = "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";
|
||||
|
||||
/**
|
||||
* The CyberChef logo with blur
|
||||
* 32x32
|
||||
*/
|
||||
export const PNG_BLUR_B64 = "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";
|
||||
|
||||
/**
|
||||
* Sunglasses smiley
|
||||
* 32x32
|
||||
Reference in new issue
Block a user