Removed CryptoJS from Utils.js. UTF8 conversion is now achieved with the much smaller and actively maintained utf8 library.
This commit is contained in:
parent
4e00ac9300
commit
0e7989111f
5
package-lock.json
generated
5
package-lock.json
generated
@ -8663,6 +8663,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"utf8": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz",
|
||||
"integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ=="
|
||||
},
|
||||
"util": {
|
||||
"version": "0.10.3",
|
||||
"resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
|
||||
|
@ -93,6 +93,7 @@
|
||||
"sladex-blowfish": "^0.8.1",
|
||||
"sortablejs": "^1.7.0",
|
||||
"split.js": "^1.3.5",
|
||||
"utf8": "^3.0.0",
|
||||
"vkbeautify": "^0.99.3",
|
||||
"xmldom": "^0.1.27",
|
||||
"xpath": "0.0.24",
|
||||
|
@ -217,4 +217,28 @@ Dish.prototype.valid = function() {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determines how much space the Dish takes up.
|
||||
* Numbers in JavaScript are 64-bit floating point, however for the purposes of the Dish,
|
||||
* we measure how many bytes are taken up when the number is written as a string.
|
||||
*
|
||||
* @returns {number}
|
||||
*/
|
||||
Dish.prototype.size = function() {
|
||||
switch (this.type) {
|
||||
case Dish.BYTE_ARRAY:
|
||||
case Dish.STRING:
|
||||
case Dish.HTML:
|
||||
return this.value.length;
|
||||
case Dish.NUMBER:
|
||||
return this.value.toString().length;
|
||||
case Dish.ARRAY_BUFFER:
|
||||
return this.value.byteLength;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export default Dish;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import CryptoJS from "crypto-js";
|
||||
import utf8 from "utf8";
|
||||
|
||||
|
||||
/**
|
||||
@ -340,6 +340,32 @@ const Utils = {
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Coverts data of varying types to a byteArray.
|
||||
* Accepts hex, Base64, UTF8 and Latin1 strings.
|
||||
*
|
||||
* @param {string} str
|
||||
* @param {string} type - One of "Hex", "Base64", "UTF8" or "Latin1"
|
||||
* @returns {byteArray}
|
||||
*
|
||||
* @example
|
||||
* // returns []
|
||||
*/
|
||||
convertToByteArray: function(str, type) {
|
||||
switch (type.toLowerCase()) {
|
||||
case "hex":
|
||||
return Utils.fromHex(str);
|
||||
case "base64":
|
||||
return Utils.fromBase64(str, null, "byteArray");
|
||||
case "utf8":
|
||||
return Utils.strToUtf8ByteArray(str);
|
||||
case "latin1":
|
||||
default:
|
||||
return Utils.strToByteArray(str);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Converts a string to a byte array.
|
||||
* Treats the string as UTF-8 if any values are over 255.
|
||||
@ -381,17 +407,17 @@ const Utils = {
|
||||
* Utils.strToUtf8ByteArray("你好");
|
||||
*/
|
||||
strToUtf8ByteArray: function(str) {
|
||||
let wordArray = CryptoJS.enc.Utf8.parse(str),
|
||||
byteArray = Utils.wordArrayToByteArray(wordArray);
|
||||
const utf8Str = utf8.encode(str);
|
||||
|
||||
if (str.length !== wordArray.sigBytes) {
|
||||
if (str.length !== utf8Str.length) {
|
||||
if (ENVIRONMENT_IS_WORKER()) {
|
||||
self.setOption("attemptHighlight", false);
|
||||
} else if (ENVIRONMENT_IS_WEB()) {
|
||||
window.app.options.attemptHighlight = false;
|
||||
}
|
||||
}
|
||||
return byteArray;
|
||||
|
||||
return Utils.strToByteArray(utf8Str);
|
||||
},
|
||||
|
||||
|
||||
@ -443,26 +469,21 @@ const Utils = {
|
||||
* Utils.byteArrayToUtf8([228,189,160,229,165,189]);
|
||||
*/
|
||||
byteArrayToUtf8: function(byteArray) {
|
||||
const str = Utils.byteArrayToChars(byteArray);
|
||||
try {
|
||||
// Try to output data as UTF-8 string
|
||||
const words = [];
|
||||
for (let i = 0; i < byteArray.length; i++) {
|
||||
words[i >>> 2] |= byteArray[i] << (24 - (i % 4) * 8);
|
||||
}
|
||||
let wordArray = new CryptoJS.lib.WordArray.init(words, byteArray.length),
|
||||
str = CryptoJS.enc.Utf8.stringify(wordArray);
|
||||
const utf8Str = utf8.decode(str);
|
||||
|
||||
if (str.length !== wordArray.sigBytes) {
|
||||
if (str.length !== utf8Str.length) {
|
||||
if (ENVIRONMENT_IS_WORKER()) {
|
||||
self.setOption("attemptHighlight", false);
|
||||
} else if (ENVIRONMENT_IS_WEB()) {
|
||||
window.app.options.attemptHighlight = false;
|
||||
}
|
||||
}
|
||||
return str;
|
||||
return utf8Str;
|
||||
} catch (err) {
|
||||
// If it fails, treat it as ANSI
|
||||
return Utils.byteArrayToChars(byteArray);
|
||||
return str;
|
||||
}
|
||||
},
|
||||
|
||||
@ -490,30 +511,6 @@ const Utils = {
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Converts a CryptoJS.lib.WordArray to a byteArray.
|
||||
*
|
||||
* @param {CryptoJS.lib.WordArray} wordArray
|
||||
* @returns {byteArray}
|
||||
*
|
||||
* @example
|
||||
* // returns [84, 101, 115, 116]
|
||||
* Utils.wordArrayToByteArray(CryptoJS.enc.Hex.parse("54657374"));
|
||||
*/
|
||||
wordArrayToByteArray: function(wordArray) {
|
||||
if (wordArray.sigBytes <= 0) return [];
|
||||
|
||||
let words = wordArray.words,
|
||||
byteArray = [];
|
||||
|
||||
for (let i = 0; i < wordArray.sigBytes; i++) {
|
||||
byteArray.push((words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff);
|
||||
}
|
||||
|
||||
return byteArray;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Base64's the input byte array using the given alphabet, returning a string.
|
||||
*
|
||||
@ -1248,21 +1245,6 @@ const Utils = {
|
||||
"None": /\s+/g // Included here to remove whitespace when there shouldn't be any
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* A mapping of string formats to their classes in the CryptoJS library.
|
||||
* @constant
|
||||
*/
|
||||
format: {
|
||||
"Hex": CryptoJS.enc.Hex,
|
||||
"Base64": CryptoJS.enc.Base64,
|
||||
"UTF8": CryptoJS.enc.Utf8,
|
||||
"UTF16": CryptoJS.enc.Utf16,
|
||||
"UTF16LE": CryptoJS.enc.Utf16LE,
|
||||
"UTF16BE": CryptoJS.enc.Utf16BE,
|
||||
"Latin1": CryptoJS.enc.Latin1,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
export default Utils;
|
||||
@ -1374,31 +1356,3 @@ Array.prototype.equals = function(other) {
|
||||
String.prototype.count = function(chr) {
|
||||
return this.split(chr).length - 1;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Library overrides ///////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Override for the CryptoJS Hex encoding parser to remove whitespace before attempting to parse
|
||||
* the hex string.
|
||||
*
|
||||
* @param {string} hexStr
|
||||
* @returns {CryptoJS.lib.WordArray}
|
||||
*/
|
||||
CryptoJS.enc.Hex.parse = function (hexStr) {
|
||||
// Remove whitespace
|
||||
hexStr = hexStr.replace(/\s/g, "");
|
||||
|
||||
// Shortcut
|
||||
const hexStrLength = hexStr.length;
|
||||
|
||||
// Convert
|
||||
const words = [];
|
||||
for (let i = 0; i < hexStrLength; i += 2) {
|
||||
words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
|
||||
}
|
||||
|
||||
return new CryptoJS.lib.WordArray.init(words, hexStrLength / 2);
|
||||
};
|
||||
|
@ -37,7 +37,6 @@ import UUID from "../../operations/UUID.js";
|
||||
*
|
||||
* Libraries:
|
||||
* - Utils.js
|
||||
* - CryptoJS
|
||||
* - otp
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
|
@ -67,7 +67,7 @@ const BitwiseOp = {
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
KEY_FORMAT: ["Hex", "Base64", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Latin1"],
|
||||
KEY_FORMAT: ["Hex", "Base64", "UTF8", "Latin1"],
|
||||
|
||||
/**
|
||||
* XOR operation.
|
||||
@ -77,12 +77,10 @@ const BitwiseOp = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runXor: function (input, args) {
|
||||
let key = Utils.format[args[0].option].parse(args[0].string || ""),
|
||||
const key = Utils.convertToByteArray(args[0].string || "", args[0].option),
|
||||
scheme = args[1],
|
||||
nullPreserving = args[2];
|
||||
|
||||
key = Utils.wordArrayToByteArray(key);
|
||||
|
||||
return BitwiseOp._bitOp(input, key, BitwiseOp._xor, nullPreserving, scheme);
|
||||
},
|
||||
|
||||
@ -200,8 +198,7 @@ const BitwiseOp = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runAnd: function (input, args) {
|
||||
let key = Utils.format[args[0].option].parse(args[0].string || "");
|
||||
key = Utils.wordArrayToByteArray(key);
|
||||
const key = Utils.convertToByteArray(args[0].string || "", args[0].option);
|
||||
|
||||
return BitwiseOp._bitOp(input, key, BitwiseOp._and);
|
||||
},
|
||||
@ -215,8 +212,7 @@ const BitwiseOp = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runOr: function (input, args) {
|
||||
let key = Utils.format[args[0].option].parse(args[0].string || "");
|
||||
key = Utils.wordArrayToByteArray(key);
|
||||
const key = Utils.convertToByteArray(args[0].string || "", args[0].option);
|
||||
|
||||
return BitwiseOp._bitOp(input, key, BitwiseOp._or);
|
||||
},
|
||||
@ -230,8 +226,7 @@ const BitwiseOp = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runAdd: function (input, args) {
|
||||
let key = Utils.format[args[0].option].parse(args[0].string || "");
|
||||
key = Utils.wordArrayToByteArray(key);
|
||||
const key = Utils.convertToByteArray(args[0].string || "", args[0].option);
|
||||
|
||||
return BitwiseOp._bitOp(input, key, BitwiseOp._add);
|
||||
},
|
||||
@ -245,8 +240,7 @@ const BitwiseOp = {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
runSub: function (input, args) {
|
||||
let key = Utils.format[args[0].option].parse(args[0].string || "");
|
||||
key = Utils.wordArrayToByteArray(key);
|
||||
const key = Utils.convertToByteArray(args[0].string || "", args[0].option);
|
||||
|
||||
return BitwiseOp._bitOp(input, key, BitwiseOp._sub);
|
||||
},
|
||||
|
@ -61,9 +61,9 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_enc: function (algo, input, args) {
|
||||
let key = Utils.format[args[0].option].parse(args[0].string || ""),
|
||||
iv = Utils.format[args[1].option].parse(args[1].string || ""),
|
||||
salt = Utils.format[args[2].option].parse(args[2].string || ""),
|
||||
let key = Cipher._format[args[0].option].parse(args[0].string || ""),
|
||||
iv = Cipher._format[args[1].option].parse(args[1].string || ""),
|
||||
salt = Cipher._format[args[2].option].parse(args[2].string || ""),
|
||||
mode = CryptoJS.mode[args[3]],
|
||||
padding = CryptoJS.pad[args[4]],
|
||||
resultOption = args[5].toLowerCase(),
|
||||
@ -83,12 +83,12 @@ const Cipher = {
|
||||
|
||||
let result = "";
|
||||
if (resultOption === "show all") {
|
||||
result += "Key: " + encrypted.key.toString(Utils.format[outputFormat]);
|
||||
result += "\nIV: " + encrypted.iv.toString(Utils.format[outputFormat]);
|
||||
if (encrypted.salt) result += "\nSalt: " + encrypted.salt.toString(Utils.format[outputFormat]);
|
||||
result += "\n\nCiphertext: " + encrypted.ciphertext.toString(Utils.format[outputFormat]);
|
||||
result += "Key: " + encrypted.key.toString(Cipher._format[outputFormat]);
|
||||
result += "\nIV: " + encrypted.iv.toString(Cipher._format[outputFormat]);
|
||||
if (encrypted.salt) result += "\nSalt: " + encrypted.salt.toString(Cipher._format[outputFormat]);
|
||||
result += "\n\nCiphertext: " + encrypted.ciphertext.toString(Cipher._format[outputFormat]);
|
||||
} else {
|
||||
result = encrypted[resultOption].toString(Utils.format[outputFormat]);
|
||||
result = encrypted[resultOption].toString(Cipher._format[outputFormat]);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -105,9 +105,9 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
_dec: function (algo, input, args) {
|
||||
let key = Utils.format[args[0].option].parse(args[0].string || ""),
|
||||
iv = Utils.format[args[1].option].parse(args[1].string || ""),
|
||||
salt = Utils.format[args[2].option].parse(args[2].string || ""),
|
||||
let key = Cipher._format[args[0].option].parse(args[0].string || ""),
|
||||
iv = Cipher._format[args[1].option].parse(args[1].string || ""),
|
||||
salt = Cipher._format[args[2].option].parse(args[2].string || ""),
|
||||
mode = CryptoJS.mode[args[3]],
|
||||
padding = CryptoJS.pad[args[4]],
|
||||
inputFormat = args[5],
|
||||
@ -118,7 +118,7 @@ const Cipher = {
|
||||
return "No input";
|
||||
}
|
||||
|
||||
const ciphertext = Utils.format[inputFormat].parse(input);
|
||||
const ciphertext = Cipher._format[inputFormat].parse(input);
|
||||
|
||||
if (iv.sigBytes === 0) {
|
||||
// Use passphrase rather than key. Need to convert it to a string.
|
||||
@ -136,7 +136,7 @@ const Cipher = {
|
||||
|
||||
let result;
|
||||
try {
|
||||
result = decrypted.toString(Utils.format[outputFormat]);
|
||||
result = decrypted.toString(Cipher._format[outputFormat]);
|
||||
} catch (err) {
|
||||
result = "Decrypt error: " + err.message;
|
||||
}
|
||||
@ -260,7 +260,7 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runBlowfishEnc: function (input, args) {
|
||||
let key = Utils.format[args[0].option].parse(args[0].string).toString(Utils.format.Latin1),
|
||||
let key = Cipher._format[args[0].option].parse(args[0].string).toString(Cipher._format.Latin1),
|
||||
mode = args[1],
|
||||
outputFormat = args[2];
|
||||
|
||||
@ -272,7 +272,7 @@ const Cipher = {
|
||||
}),
|
||||
enc = CryptoJS.enc.Hex.parse(encHex);
|
||||
|
||||
return enc.toString(Utils.format[outputFormat]);
|
||||
return enc.toString(Cipher._format[outputFormat]);
|
||||
},
|
||||
|
||||
|
||||
@ -284,13 +284,13 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runBlowfishDec: function (input, args) {
|
||||
let key = Utils.format[args[0].option].parse(args[0].string).toString(Utils.format.Latin1),
|
||||
let key = Cipher._format[args[0].option].parse(args[0].string).toString(Cipher._format.Latin1),
|
||||
mode = args[1],
|
||||
inputFormat = args[2];
|
||||
|
||||
if (key.length === 0) return "Enter a key";
|
||||
|
||||
input = Utils.format[inputFormat].parse(input);
|
||||
input = Cipher._format[inputFormat].parse(input);
|
||||
|
||||
return Blowfish.decrypt(input.toString(CryptoJS.enc.Base64), key, {
|
||||
outputType: 0, // This actually means inputType. The library is weird.
|
||||
@ -329,14 +329,14 @@ const Cipher = {
|
||||
salt = CryptoJS.enc.Hex.parse(args[3] || ""),
|
||||
inputFormat = args[4],
|
||||
outputFormat = args[5],
|
||||
passphrase = Utils.format[inputFormat].parse(input),
|
||||
passphrase = Cipher._format[inputFormat].parse(input),
|
||||
key = CryptoJS.PBKDF2(passphrase, salt, {
|
||||
keySize: keySize,
|
||||
hasher: CryptoJS.algo[hasher],
|
||||
iterations: iterations,
|
||||
});
|
||||
|
||||
return key.toString(Utils.format[outputFormat]);
|
||||
return key.toString(Cipher._format[outputFormat]);
|
||||
},
|
||||
|
||||
|
||||
@ -354,14 +354,14 @@ const Cipher = {
|
||||
salt = CryptoJS.enc.Hex.parse(args[3] || ""),
|
||||
inputFormat = args[4],
|
||||
outputFormat = args[5],
|
||||
passphrase = Utils.format[inputFormat].parse(input),
|
||||
passphrase = Cipher._format[inputFormat].parse(input),
|
||||
key = CryptoJS.EvpKDF(passphrase, salt, {
|
||||
keySize: keySize,
|
||||
hasher: CryptoJS.algo[hasher],
|
||||
iterations: iterations,
|
||||
});
|
||||
|
||||
return key.toString(Utils.format[outputFormat]);
|
||||
return key.toString(Cipher._format[outputFormat]);
|
||||
},
|
||||
|
||||
|
||||
@ -373,11 +373,11 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runRc4: function (input, args) {
|
||||
let message = Utils.format[args[1]].parse(input),
|
||||
passphrase = Utils.format[args[0].option].parse(args[0].string),
|
||||
let message = Cipher._format[args[1]].parse(input),
|
||||
passphrase = Cipher._format[args[0].option].parse(args[0].string),
|
||||
encrypted = CryptoJS.RC4.encrypt(message, passphrase);
|
||||
|
||||
return encrypted.ciphertext.toString(Utils.format[args[2]]);
|
||||
return encrypted.ciphertext.toString(Cipher._format[args[2]]);
|
||||
},
|
||||
|
||||
|
||||
@ -395,12 +395,12 @@ const Cipher = {
|
||||
* @returns {string}
|
||||
*/
|
||||
runRc4drop: function (input, args) {
|
||||
let message = Utils.format[args[1]].parse(input),
|
||||
passphrase = Utils.format[args[0].option].parse(args[0].string),
|
||||
let message = Cipher._format[args[1]].parse(input),
|
||||
passphrase = Cipher._format[args[0].option].parse(args[0].string),
|
||||
drop = args[3],
|
||||
encrypted = CryptoJS.RC4Drop.encrypt(message, passphrase, { drop: drop });
|
||||
|
||||
return encrypted.ciphertext.toString(Utils.format[args[2]]);
|
||||
return encrypted.ciphertext.toString(Cipher._format[args[2]]);
|
||||
},
|
||||
|
||||
|
||||
@ -783,6 +783,23 @@ const Cipher = {
|
||||
return output;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* A mapping of string formats to their classes in the CryptoJS library.
|
||||
*
|
||||
* @private
|
||||
* @constant
|
||||
*/
|
||||
_format: {
|
||||
"Hex": CryptoJS.enc.Hex,
|
||||
"Base64": CryptoJS.enc.Base64,
|
||||
"UTF8": CryptoJS.enc.Utf8,
|
||||
"UTF16": CryptoJS.enc.Utf16,
|
||||
"UTF16LE": CryptoJS.enc.Utf16LE,
|
||||
"UTF16BE": CryptoJS.enc.Utf16BE,
|
||||
"Latin1": CryptoJS.enc.Latin1,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
export default Cipher;
|
||||
@ -827,3 +844,27 @@ CryptoJS.kdf.OpenSSL.execute = function (password, keySize, ivSize, salt) {
|
||||
// Return params
|
||||
return CryptoJS.lib.CipherParams.create({ key: key, iv: iv, salt: salt });
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Override for the CryptoJS Hex encoding parser to remove whitespace before attempting to parse
|
||||
* the hex string.
|
||||
*
|
||||
* @param {string} hexStr
|
||||
* @returns {CryptoJS.lib.WordArray}
|
||||
*/
|
||||
CryptoJS.enc.Hex.parse = function (hexStr) {
|
||||
// Remove whitespace
|
||||
hexStr = hexStr.replace(/\s/g, "");
|
||||
|
||||
// Shortcut
|
||||
const hexStrLength = hexStr.length;
|
||||
|
||||
// Convert
|
||||
const words = [];
|
||||
for (let i = 0; i < hexStrLength; i += 2) {
|
||||
words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
|
||||
}
|
||||
|
||||
return new CryptoJS.lib.WordArray.init(words, hexStrLength / 2);
|
||||
};
|
||||
|
@ -402,7 +402,7 @@ HighlighterWaiter.prototype.highlight = function(textarea, highlighter, pos) {
|
||||
|
||||
// Check if there is a carriage return in the output dish as this will not
|
||||
// be displayed by the HTML textarea and will mess up highlighting offsets.
|
||||
if (!this.app.dishStr || this.app.dishStr.indexOf("\r") >= 0) return false;
|
||||
if (this.manager.output.containsCR()) return false;
|
||||
|
||||
const startPlaceholder = "[startHighlight]";
|
||||
const startPlaceholderRegex = /\[startHighlight\]/g;
|
||||
|
@ -282,4 +282,14 @@ OutputWaiter.prototype.setStatusMsg = function(msg) {
|
||||
el.textContent = msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the output contains carriage returns
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
OutputWaiter.prototype.containsCR = function() {
|
||||
return this.app.dishStr.indexOf("\r") >= 0;
|
||||
};
|
||||
|
||||
export default OutputWaiter;
|
||||
|
Loading…
x
Reference in New Issue
Block a user