Add repeating XOR encryption
This commit is contained in:
parent
a18092cb6a
commit
20c2af05ec
18
basics.ts
18
basics.ts
@ -103,3 +103,21 @@ export const detectSingleByteXor: DetectSingleByteXor = (buffs) => {
|
|||||||
candidates.sort((a, b) => b[0] - a[0]);
|
candidates.sort((a, b) => b[0] - a[0]);
|
||||||
return candidates[0][1];
|
return candidates[0][1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type EncryptRepeatingXOR = (buff: Buffer, key: Buffer) => Buffer;
|
||||||
|
export const encryptRepeatingXOR: EncryptRepeatingXOR = (buff, key) => {
|
||||||
|
const resBuff = Buffer.alloc(buff.length);
|
||||||
|
range(0, buff.length).forEach(i => {
|
||||||
|
resBuff[i] = buff[i] ^ key[i % key.length];
|
||||||
|
});
|
||||||
|
return resBuff;
|
||||||
|
};
|
||||||
|
|
||||||
|
type DecryptRepeatingXOR = (buff: Buffer, key: Buffer) => Buffer;
|
||||||
|
export const decryptRepeatingXOR: DecryptRepeatingXOR = (buff, key) => {
|
||||||
|
const resBuff = Buffer.alloc(buff.length);
|
||||||
|
range(0, buff.length).forEach(i => {
|
||||||
|
resBuff[i] = buff[i] ^ key[i % key.length];
|
||||||
|
});
|
||||||
|
return resBuff;
|
||||||
|
};
|
||||||
|
2
data/repeatingXOR.txt
Normal file
2
data/repeatingXOR.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Burning 'em, if you ain't quick and nimble
|
||||||
|
I go crazy when I hear a cymbal
|
@ -2,10 +2,10 @@ import test from 'node:test';
|
|||||||
import * as path from 'node:path';
|
import * as path from 'node:path';
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
|
|
||||||
const DATA_PATH = path.join(__dirname, '..', 'data');
|
|
||||||
|
|
||||||
import { range, fileToBuff } from '../utils';
|
import { range, fileToBuff } from '../utils';
|
||||||
import { hexToBuff, buffTo64, xorBuffers, encryptSingleByte, decryptSingleByte, crackSingleByteKeyMsg, detectSingleByteXor } from '../basics';
|
import { hexToBuff, buffTo64, xorBuffers, encryptSingleByte, decryptSingleByte, crackSingleByteKeyMsg, detectSingleByteXor, encryptRepeatingXOR, decryptRepeatingXOR } from '../basics';
|
||||||
|
|
||||||
|
const DATA_PATH = path.join(__dirname, '..', 'data');
|
||||||
|
|
||||||
test('range', () => {
|
test('range', () => {
|
||||||
assert.deepEqual(range(0, 10), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
assert.deepEqual(range(0, 10), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||||
@ -42,3 +42,18 @@ test('detect single byte xor', () => {
|
|||||||
const expected = 'Now that the party is jumping';
|
const expected = 'Now that the party is jumping';
|
||||||
assert.equal(detectSingleByteXor(input), expected);
|
assert.equal(detectSingleByteXor(input), expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('encrypt/decrypt repeating xor is symmetric', () => {
|
||||||
|
const input = 'random input to test this stuff outeqw e991231293 129083 h1207018 9';
|
||||||
|
const key = 'also random';
|
||||||
|
assert.equal(
|
||||||
|
decryptRepeatingXOR(encryptRepeatingXOR(Buffer.from(input, 'utf-8'), Buffer.from(key, 'utf-8')), Buffer.from(key, 'utf-8')).toString('utf-8'), input);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('encrypt repeating xor', () => {
|
||||||
|
const input = fileToBuff(path.join(DATA_PATH, 'repeatingXOR.txt'), 'utf-8');
|
||||||
|
const parsedInput = Buffer.from(input.map(buff => buff.toString('utf-8')).join('\n'));
|
||||||
|
const key = 'ICE';
|
||||||
|
const expected = '0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f';
|
||||||
|
assert.equal(encryptRepeatingXOR(parsedInput, Buffer.from(key, 'utf-8')).toString('hex'), expected);
|
||||||
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user