-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdecrypt.ts
More file actions
102 lines (87 loc) · 4.3 KB
/
decrypt.ts
File metadata and controls
102 lines (87 loc) · 4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import * as readline from 'readline';
import * as crypto from 'crypto';
import keysConfig from './keys.json';
import {
decryptSubstitution,
decryptCaesar,
railFenceDecrypt,
removeHiddenPadding,
getKeyShifts,
getRepeatingShifts,
decryptMath,
stretchKey,
generateHMAC,
deriveKeys,
aesDecrypt,
getPipelineOrder
} from './cipher';
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
function question(query: string): Promise<string> {
return new Promise(resolve => rl.question(query, resolve));
}
async function main() {
try {
const payloadBase64 = await question("Enter the secure JSON payload (Base64 wrapper): ");
let numRoundsStr = await question("Enter the number of rounds for decryption: ");
let numRounds = parseInt(numRoundsStr) || 1;
const key = await question("Enter the key used for encryption: ");
const jsonStr = Buffer.from(payloadBase64, 'base64').toString('utf-8');
const payloadObj = JSON.parse(jsonStr);
const { data, hmac, salt, iv, tag } = payloadObj;
const masterKeyBuffer = stretchKey(key, salt);
const { aesKey, hmacKey } = deriveKeys(masterKeyBuffer, salt);
const masterKeyHex = masterKeyBuffer.toString('hex');
const masterPipeline = (keysConfig as any).MASTER_PIPELINE;
const legacyKeyShifts = getKeyShifts(key);
const legacyRepeatingShifts = getRepeatingShifts(legacyKeyShifts, numRounds);
let state = data; // Target payload starts as the base64 data
// Determination: If the last stage (forward) was not AES, we must decode the transport layer first.
const lastStageForward = masterPipeline[masterPipeline.length - 1];
if (lastStageForward !== "aes" || !((keysConfig as any).AES_ENABLED)) {
state = Buffer.from(state, 'base64').toString('utf16le');
}
for (let i = masterPipeline.length - 1; i >= 0; i--) {
const stage = masterPipeline[i];
if (stage === "hmac" && (keysConfig as any).ENABLE_HMAC) {
const hmacPayload = state + salt + iv + tag;
const calculatedHmac = generateHMAC(hmacKey, hmacPayload);
if (calculatedHmac !== hmac) {
throw new Error("AUTHENTICATION FAILED: Data corruption or tampering detected (HMAC mismatch)!");
}
} else if (stage === "aes" && (keysConfig as any).AES_ENABLED) {
state = aesDecrypt(state, aesKey, iv, tag);
} else if (stage === "padding") {
state = removeHiddenPadding(state);
} else if (stage === "chaos") {
let chaosText = state;
for (let round = numRounds - 1; round >= 0; round--) {
const legacyRoundShift = legacyRepeatingShifts[round];
const roundDigest = crypto.createHash('sha256').update(masterKeyHex + round.toString() + legacyRoundShift.toString()).digest();
const shift = roundDigest[0];
const modifier = roundDigest[1];
const pipelineOrder = getPipelineOrder(modifier);
for (let s = pipelineOrder.length - 1; s >= 0; s--) {
const step = pipelineOrder[s];
if (step === "math" && (keysConfig as any).ENABLE_MATH_LAYER) chaosText = decryptMath(chaosText, shift);
if (step === "rail_fence" && (keysConfig as any).ENABLE_RAIL_FENCE_LAYER) chaosText = railFenceDecrypt(chaosText);
if (step === "substitution" && (keysConfig as any).ENABLE_SUBSTITUTION_LAYER) chaosText = decryptSubstitution(chaosText);
if (step === "caesar" && (keysConfig as any).ENABLE_CAESAR_LAYER) chaosText = decryptCaesar(chaosText, shift);
}
}
state = chaosText;
} else if (stage === "substitution" && (keysConfig as any).ENABLE_SUBSTITUTION_LAYER) {
state = decryptSubstitution(state);
}
}
const decryptedText = state;
console.log(`\nFinal decrypted text: ${decryptedText}\n`);
} catch (err) {
console.error(err);
} finally {
rl.close();
}
}
main();