-
Notifications
You must be signed in to change notification settings - Fork 4
/
rc4.ts
78 lines (72 loc) · 2.06 KB
/
rc4.ts
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
/**
* An inline-based implementation of the RC4 stream cipher.
*/
export class RC4 {
private state: Buffer;
private key: Buffer;
private i: number;
private j: number;
/**
* Constructs a new RC4 cipher object and initializes
* the Keystream State with the given key.
* @param key The key to use in the Keystream.
*/
constructor(key: Buffer) {
if (!Buffer.isBuffer(key)) {
throw new TypeError(`Parameter "key" must be a Buffer, not ${typeof key}`);
}
this.key = key;
this.reset();
}
/**
* Performs an inline cipher on the entire contents of the `data` buffer.
* @param data A stream of data to cipher using the Keystream.
*/
cipher(data: Buffer): void {
for (let n = 0; n < data.length; n++) {
this.i = (this.i + 1) % 256;
this.j = (this.j + this.state[this.i]) % 256;
const tmp = this.state[this.i];
this.state[this.i] = this.state[this.j];
this.state[this.j] = tmp;
const k = this.state[(this.state[this.i] + this.state[this.j]) % 256];
/* tslint:disable no-bitwise */
data[n] = (data[n] ^ k);
/* tslint:enable no-bitwise */
}
}
/**
* Initializes the Keystream State.
*/
reset(): void {
this.state = Buffer.alloc(256);
this.i = 0;
this.j = 0;
for (let i = 0; i < 256; i++) {
this.state[i] = i;
}
let j = 0;
for (let i = 0; i < 256; i++) {
j = (j + this.state[i] + this.key[i % this.key.length]) % 256;
const tmp = this.state[i];
this.state[i] = this.state[j];
this.state[j] = tmp;
}
}
}
/**
* The RC4 Private Key used to encrypt outgoing packet.
* This key is a Hex String, so should be converted to
* a Buffer for use.
* @example
* const key = Buffer.from(OUTGOING_KEY, 'hex');
*/
export const OUTGOING_KEY = '6a39570cc9de4ec71d64821894';
/**
* The RC4 Private Key to decrypt incoming packet data.
* This key is a Hex String, so should be converted to
* a Buffer for use.
* @example
* const key = Buffer.from(INCOMING_KEY, 'hex');
*/
export const INCOMING_KEY = 'c79332b197f92ba85ed281a023';