mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-21 23:36:16 -04:00
ESM: Added remaining Base64 ops and created a Base64 library. Added the prefer-const eslint rule.
This commit is contained in:
parent
9b4fc3d3aa
commit
041cd9fb8e
30 changed files with 986 additions and 825 deletions
90
src/core/operations/FromBase32.mjs
Normal file
90
src/core/operations/FromBase32.mjs
Normal file
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
|
||||
/**
|
||||
* From Base32 operation
|
||||
*/
|
||||
class FromBase32 extends Operation {
|
||||
|
||||
/**
|
||||
* FromBase32 constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "From Base32";
|
||||
this.module = "Default";
|
||||
this.description = "Base32 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.";
|
||||
this.inputType = "string";
|
||||
this.outputType = "byteArray";
|
||||
this.args = [
|
||||
{
|
||||
name: "Alphabet",
|
||||
type: "binaryString",
|
||||
value: "A-Z2-7="
|
||||
},
|
||||
{
|
||||
name: "Remove non-alphabet chars",
|
||||
type: "boolean",
|
||||
value: true
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
run(input, args) {
|
||||
if (!input) return [];
|
||||
|
||||
const alphabet = args[0] ?
|
||||
Utils.expandAlphRange(args[0]).join("") : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",
|
||||
removeNonAlphChars = args[1],
|
||||
output = [];
|
||||
|
||||
let chr1, chr2, chr3, chr4, chr5,
|
||||
enc1, enc2, enc3, enc4, enc5, enc6, enc7, enc8,
|
||||
i = 0;
|
||||
|
||||
if (removeNonAlphChars) {
|
||||
const re = new RegExp("[^" + alphabet.replace(/[\]\\\-^]/g, "\\$&") + "]", "g");
|
||||
input = input.replace(re, "");
|
||||
}
|
||||
|
||||
while (i < input.length) {
|
||||
enc1 = alphabet.indexOf(input.charAt(i++));
|
||||
enc2 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc3 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc4 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc5 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc6 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc7 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
enc8 = alphabet.indexOf(input.charAt(i++) || "=");
|
||||
|
||||
chr1 = (enc1 << 3) | (enc2 >> 2);
|
||||
chr2 = ((enc2 & 3) << 6) | (enc3 << 1) | (enc4 >> 4);
|
||||
chr3 = ((enc4 & 15) << 4) | (enc5 >> 1);
|
||||
chr4 = ((enc5 & 1) << 7) | (enc6 << 2) | (enc7 >> 3);
|
||||
chr5 = ((enc7 & 7) << 5) | enc8;
|
||||
|
||||
output.push(chr1);
|
||||
if (enc2 & 3 !== 0 || enc3 !== 32) output.push(chr2);
|
||||
if (enc4 & 15 !== 0 || enc5 !== 32) output.push(chr3);
|
||||
if (enc5 & 1 !== 0 || enc6 !== 32) output.push(chr4);
|
||||
if (enc7 & 7 !== 0 || enc8 !== 32) output.push(chr5);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default FromBase32;
|
|
@ -5,8 +5,7 @@
|
|||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
import {ALPHABET, ALPHABET_OPTIONS} from "../lib/Base64";
|
||||
import {fromBase64, ALPHABET_OPTIONS} from "../lib/Base64";
|
||||
|
||||
/**
|
||||
* From Base64 operation
|
||||
|
@ -14,17 +13,17 @@ import {ALPHABET, ALPHABET_OPTIONS} from "../lib/Base64";
|
|||
class FromBase64 extends Operation {
|
||||
|
||||
/**
|
||||
* ToBase64 constructor
|
||||
* FromBase64 constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "From Base64";
|
||||
this.module = "Default";
|
||||
this.name = "From Base64";
|
||||
this.module = "Default";
|
||||
this.description = "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.<br><br>This operation decodes data from an ASCII Base64 string back into its raw format.<br><br>e.g. <code>aGVsbG8=</code> becomes <code>hello</code>";
|
||||
this.inputType = "string";
|
||||
this.outputType = "byteArray";
|
||||
this.args = [
|
||||
this.inputType = "string";
|
||||
this.outputType = "byteArray";
|
||||
this.args = [
|
||||
{
|
||||
name: "Alphabet",
|
||||
type: "editableOption",
|
||||
|
@ -44,10 +43,9 @@ class FromBase64 extends Operation {
|
|||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
let alphabet = args[0] || ALPHABET,
|
||||
removeNonAlphChars = args[1];
|
||||
const [alphabet, removeNonAlphChars] = args;
|
||||
|
||||
return Utils.fromBase64(input, alphabet, "byteArray", removeNonAlphChars);
|
||||
return fromBase64(input, alphabet, "byteArray", removeNonAlphChars);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
162
src/core/operations/ShowBase64Offsets.mjs
Normal file
162
src/core/operations/ShowBase64Offsets.mjs
Normal file
|
@ -0,0 +1,162 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
import {fromBase64, toBase64} from "../lib/Base64";
|
||||
|
||||
/**
|
||||
* Show Base64 offsets operation
|
||||
*/
|
||||
class ShowBase64Offsets extends Operation {
|
||||
|
||||
/**
|
||||
* ShowBase64Offsets constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Show Base64 offsets";
|
||||
this.module = "Default";
|
||||
this.description = "When a string is within a block of data and the whole block is Base64'd, the string itself could be represented in Base64 in three distinct ways depending on its offset within the block.<br><br>This operation shows all possible offsets for a given string so that each possible encoding can be considered.";
|
||||
this.inputType = "byteArray";
|
||||
this.outputType = "html";
|
||||
this.args = [
|
||||
{
|
||||
name: "Alphabet",
|
||||
type: "binaryString",
|
||||
value: "A-Za-z0-9+/="
|
||||
},
|
||||
{
|
||||
name: "Show variable chars and padding",
|
||||
type: "boolean",
|
||||
value: true
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {byteArray} input
|
||||
* @param {Object[]} args
|
||||
* @returns {html}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [alphabet, showVariable] = args;
|
||||
|
||||
let offset0 = toBase64(input, alphabet),
|
||||
offset1 = toBase64([0].concat(input), alphabet),
|
||||
offset2 = toBase64([0, 0].concat(input), alphabet),
|
||||
staticSection = "",
|
||||
padding = "";
|
||||
|
||||
const len0 = offset0.indexOf("="),
|
||||
len1 = offset1.indexOf("="),
|
||||
len2 = offset2.indexOf("="),
|
||||
script = "<script type='application/javascript'>$('[data-toggle=\"tooltip\"]').tooltip()</script>";
|
||||
|
||||
if (input.length < 1) {
|
||||
return "Please enter a string.";
|
||||
}
|
||||
|
||||
// Highlight offset 0
|
||||
if (len0 % 4 === 2) {
|
||||
staticSection = offset0.slice(0, -3);
|
||||
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64(staticSection, alphabet).slice(0, -2)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset0.substr(offset0.length - 3, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset0.substr(offset0.length - 2) + "</span>";
|
||||
} else if (len0 % 4 === 3) {
|
||||
staticSection = offset0.slice(0, -2);
|
||||
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64(staticSection, alphabet).slice(0, -1)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset0.substr(offset0.length - 2, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset0.substr(offset0.length - 1) + "</span>";
|
||||
} else {
|
||||
staticSection = offset0;
|
||||
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64(staticSection, alphabet)) + "'>" +
|
||||
staticSection + "</span>";
|
||||
}
|
||||
|
||||
if (!showVariable) {
|
||||
offset0 = staticSection;
|
||||
}
|
||||
|
||||
|
||||
// Highlight offset 1
|
||||
padding = "<span class='hl3'>" + offset1.substr(0, 1) + "</span>" +
|
||||
"<span class='hl5'>" + offset1.substr(1, 1) + "</span>";
|
||||
offset1 = offset1.substr(2);
|
||||
if (len1 % 4 === 2) {
|
||||
staticSection = offset1.slice(0, -3);
|
||||
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64("AA" + staticSection, alphabet).slice(1, -2)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset1.substr(offset1.length - 3, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset1.substr(offset1.length - 2) + "</span>";
|
||||
} else if (len1 % 4 === 3) {
|
||||
staticSection = offset1.slice(0, -2);
|
||||
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64("AA" + staticSection, alphabet).slice(1, -1)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset1.substr(offset1.length - 2, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset1.substr(offset1.length - 1) + "</span>";
|
||||
} else {
|
||||
staticSection = offset1;
|
||||
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64("AA" + staticSection, alphabet).slice(1)) + "'>" +
|
||||
staticSection + "</span>";
|
||||
}
|
||||
|
||||
if (!showVariable) {
|
||||
offset1 = staticSection;
|
||||
}
|
||||
|
||||
// Highlight offset 2
|
||||
padding = "<span class='hl3'>" + offset2.substr(0, 2) + "</span>" +
|
||||
"<span class='hl5'>" + offset2.substr(2, 1) + "</span>";
|
||||
offset2 = offset2.substr(3);
|
||||
if (len2 % 4 === 2) {
|
||||
staticSection = offset2.slice(0, -3);
|
||||
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset2.substr(offset2.length - 3, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset2.substr(offset2.length - 2) + "</span>";
|
||||
} else if (len2 % 4 === 3) {
|
||||
staticSection = offset2.slice(0, -2);
|
||||
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
|
||||
staticSection + "</span>" +
|
||||
"<span class='hl5'>" + offset2.substr(offset2.length - 2, 1) + "</span>" +
|
||||
"<span class='hl3'>" + offset2.substr(offset2.length - 1) + "</span>";
|
||||
} else {
|
||||
staticSection = offset2;
|
||||
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
||||
Utils.escapeHtml(fromBase64("AAA" + staticSection, alphabet).slice(2)) + "'>" +
|
||||
staticSection + "</span>";
|
||||
}
|
||||
|
||||
if (!showVariable) {
|
||||
offset2 = staticSection;
|
||||
}
|
||||
|
||||
return (showVariable ? "Characters highlighted in <span class='hl5'>green</span> could change if the input is surrounded by more data." +
|
||||
"\nCharacters highlighted in <span class='hl3'>red</span> are for padding purposes only." +
|
||||
"\nUnhighlighted characters are <span data-toggle='tooltip' data-placement='top' title='Tooltip on left'>static</span>." +
|
||||
"\nHover over the static sections to see what they decode to on their own.\n" +
|
||||
"\nOffset 0: " + offset0 +
|
||||
"\nOffset 1: " + offset1 +
|
||||
"\nOffset 2: " + offset2 +
|
||||
script :
|
||||
offset0 + "\n" + offset1 + "\n" + offset2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ShowBase64Offsets;
|
85
src/core/operations/ToBase32.mjs
Normal file
85
src/core/operations/ToBase32.mjs
Normal file
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
|
||||
/**
|
||||
* To Base32 operation
|
||||
*/
|
||||
class ToBase32 extends Operation {
|
||||
|
||||
/**
|
||||
* ToBase32 constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "To Base32";
|
||||
this.module = "Default";
|
||||
this.description = "Base32 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.";
|
||||
this.inputType = "byteArray";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Alphabet",
|
||||
type: "binaryString",
|
||||
value: "A-Z2-7="
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {byteArray} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
if (!input) return "";
|
||||
|
||||
const alphabet = args[0] ? Utils.expandAlphRange(args[0]).join("") : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=";
|
||||
let output = "",
|
||||
chr1, chr2, chr3, chr4, chr5,
|
||||
enc1, enc2, enc3, enc4, enc5, enc6, enc7, enc8,
|
||||
i = 0;
|
||||
|
||||
while (i < input.length) {
|
||||
chr1 = input[i++];
|
||||
chr2 = input[i++];
|
||||
chr3 = input[i++];
|
||||
chr4 = input[i++];
|
||||
chr5 = input[i++];
|
||||
|
||||
enc1 = chr1 >> 3;
|
||||
enc2 = ((chr1 & 7) << 2) | (chr2 >> 6);
|
||||
enc3 = (chr2 >> 1) & 31;
|
||||
enc4 = ((chr2 & 1) << 4) | (chr3 >> 4);
|
||||
enc5 = ((chr3 & 15) << 1) | (chr4 >> 7);
|
||||
enc6 = (chr4 >> 2) & 31;
|
||||
enc7 = ((chr4 & 3) << 3) | (chr5 >> 5);
|
||||
enc8 = chr5 & 31;
|
||||
|
||||
if (isNaN(chr2)) {
|
||||
enc3 = enc4 = enc5 = enc6 = enc7 = enc8 = 32;
|
||||
} else if (isNaN(chr3)) {
|
||||
enc5 = enc6 = enc7 = enc8 = 32;
|
||||
} else if (isNaN(chr4)) {
|
||||
enc6 = enc7 = enc8 = 32;
|
||||
} else if (isNaN(chr5)) {
|
||||
enc8 = 32;
|
||||
}
|
||||
|
||||
output += alphabet.charAt(enc1) + alphabet.charAt(enc2) + alphabet.charAt(enc3) +
|
||||
alphabet.charAt(enc4) + alphabet.charAt(enc5) + alphabet.charAt(enc6) +
|
||||
alphabet.charAt(enc7) + alphabet.charAt(enc8);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ToBase32;
|
|
@ -5,8 +5,7 @@
|
|||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
import {ALPHABET, ALPHABET_OPTIONS} from "../lib/Base64";
|
||||
import {toBase64, ALPHABET_OPTIONS} from "../lib/Base64";
|
||||
|
||||
/**
|
||||
* To Base64 operation
|
||||
|
@ -19,12 +18,12 @@ class ToBase64 extends Operation {
|
|||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "To Base64";
|
||||
this.module = "Default";
|
||||
this.name = "To Base64";
|
||||
this.module = "Default";
|
||||
this.description = "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.<br><br>This operation decodes data from an ASCII Base64 string back into its raw format.<br><br>e.g. <code>aGVsbG8=</code> becomes <code>hello</code>";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Alphabet",
|
||||
type: "editableOption",
|
||||
|
@ -39,8 +38,8 @@ class ToBase64 extends Operation {
|
|||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const alphabet = args[0] || ALPHABET;
|
||||
return Utils.toBase64(new Uint8Array(input), alphabet);
|
||||
const alphabet = args[0];
|
||||
return toBase64(new Uint8Array(input), alphabet);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
import ToBase64 from "./ToBase64";
|
||||
import FromBase64 from "./FromBase64";
|
||||
import ToBase32 from "./ToBase32";
|
||||
import FromBase32 from "./FromBase32";
|
||||
import ShowBase64Offsets from "./ShowBase64Offsets";
|
||||
|
||||
export default [
|
||||
export {
|
||||
ToBase64,
|
||||
FromBase64
|
||||
];
|
||||
FromBase64,
|
||||
ToBase32,
|
||||
FromBase32,
|
||||
ShowBase64Offsets
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Utils from "../Utils.js";
|
||||
import {toBase64} from "../lib/Base64";
|
||||
import CryptoJS from "crypto-js";
|
||||
import forge from "imports-loader?jQuery=>null!node-forge/dist/forge.min.js";
|
||||
import {blowfish as Blowfish} from "sladex-blowfish";
|
||||
|
@ -366,7 +367,7 @@ DES uses a key length of 8 bytes (64 bits).`;
|
|||
|
||||
input = Utils.convertToByteString(input, inputType);
|
||||
|
||||
Blowfish.setIV(Utils.toBase64(iv), 0);
|
||||
Blowfish.setIV(toBase64(iv), 0);
|
||||
|
||||
const enc = Blowfish.encrypt(input, key, {
|
||||
outputType: Cipher._BLOWFISH_OUTPUT_TYPE_LOOKUP[outputType],
|
||||
|
@ -395,7 +396,7 @@ DES uses a key length of 8 bytes (64 bits).`;
|
|||
|
||||
input = inputType === "Raw" ? Utils.strToByteArray(input) : input;
|
||||
|
||||
Blowfish.setIV(Utils.toBase64(iv), 0);
|
||||
Blowfish.setIV(toBase64(iv), 0);
|
||||
|
||||
const result = Blowfish.decrypt(input, key, {
|
||||
outputType: Cipher._BLOWFISH_OUTPUT_TYPE_LOOKUP[inputType], // This actually means inputType. The library is weird.
|
||||
|
|
|
@ -2,6 +2,7 @@ import * as ExifParser from "exif-parser";
|
|||
import removeEXIF from "../vendor/remove-exif.js";
|
||||
import Utils from "../Utils.js";
|
||||
import FileType from "./FileType.js";
|
||||
import {fromBase64, toBase64} from "../lib/Base64";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -96,7 +97,7 @@ const Image = {
|
|||
case "Base64":
|
||||
// Don't trust the Base64 entered by the user.
|
||||
// Unwrap it first, then re-encode later.
|
||||
input = Utils.fromBase64(input, null, "byteArray");
|
||||
input = fromBase64(input, null, "byteArray");
|
||||
break;
|
||||
case "Raw":
|
||||
default:
|
||||
|
@ -113,7 +114,7 @@ const Image = {
|
|||
}
|
||||
|
||||
// Add image data to URI
|
||||
dataURI += "base64," + Utils.toBase64(input);
|
||||
dataURI += "base64," + toBase64(input);
|
||||
|
||||
return "<img src='" + dataURI + "'>";
|
||||
},
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Utils from "../Utils.js";
|
||||
import {fromBase64} from "../lib/Base64";
|
||||
import * as r from "jsrsasign";
|
||||
|
||||
|
||||
|
@ -43,7 +44,7 @@ const PublicKey = {
|
|||
cert.readCertPEM(input);
|
||||
break;
|
||||
case "Base64":
|
||||
cert.readCertHex(Utils.toHex(Utils.fromBase64(input, null, "byteArray"), ""));
|
||||
cert.readCertHex(Utils.toHex(fromBase64(input, null, "byteArray"), ""));
|
||||
break;
|
||||
case "Raw":
|
||||
cert.readCertHex(Utils.toHex(Utils.strToByteArray(input), ""));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue