DES3.js
4.5 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
103
104
105
106
107
108
109
110
111
import { SerializableCipher } from "./lib/algorithm/cipher/SerializableCipher";
import { BlockCipher } from "./lib/algorithm/cipher/BlockCipher";
import { Cipher } from "./lib/algorithm/cipher/Cipher";
import { DES } from "./DES";
import { Word32Array } from "./lib/Word32Array";
import { PasswordBasedCipher } from "./lib/algorithm/cipher/PasswordBasedCipher";
export class DES3 extends BlockCipher {
constructor(props) {
super(props);
this._blockSize = 64 / 32;
this._props = props;
const TripleDES = this._get3DES();
// Create DES instances
this._des1 = TripleDES[0];
this._des2 = TripleDES[1];
this._des3 = TripleDES[2];
}
_get3DES() {
// Shortcuts
const key = this._key;
const keyWords = key.words;
// Make sure the key length is valid (64, 128 or >= 192 bit)
if (keyWords.length !== 2 && keyWords.length !== 4 && keyWords.length < 6) {
throw new Error("Invalid key length - 3DES requires the key length to be 64, 128, 192 or >192.");
}
// Extend the key according to the keying options defined in 3DES standard
const key1 = keyWords.slice(0, 2);
const key2 = keyWords.length < 4 ? keyWords.slice(0, 2) : keyWords.slice(2, 4);
const key3 = keyWords.length < 6 ? keyWords.slice(0, 2) : keyWords.slice(4, 6);
// Create DES instances
const des1 = DES.createEncryptor(new Word32Array(key1));
const des2 = DES.createEncryptor(new Word32Array(key2));
const des3 = DES.createEncryptor(new Word32Array(key3));
return [des1, des2, des3];
}
_doReset() {
const TripleDES = this._get3DES();
// Create DES instances
this._des1 = TripleDES[0];
this._des2 = TripleDES[1];
this._des3 = TripleDES[2];
}
encryptBlock(words, offset) {
this._des1.encryptBlock(words, offset);
this._des2.decryptBlock(words, offset);
this._des3.encryptBlock(words, offset);
}
decryptBlock(words, offset) {
this._des3.decryptBlock(words, offset);
this._des2.encryptBlock(words, offset);
this._des1.decryptBlock(words, offset);
}
/**
* Creates this cipher in encryption mode.
*
* @param {Word32Array} key The key.
* @param {Partial<CipherProps>?} props (Optional) The configuration options to use for this operation.
* @return {Cipher} A cipher instance.
* @example
* var cipher = DES3.createEncryptor(keyWordArray, { iv: ivWordArray });
*/
static createEncryptor(key, props) {
props = typeof props === "undefined" ? {} : props;
return new DES3(Object.assign(Object.assign({}, props), { key, transformMode: Cipher.ENC_TRANSFORM_MODE }));
}
/**
* Creates this cipher in decryption mode.
*
* @param {Word32Array} key The key.
* @param {Partial<CipherProps>?} props (Optional) The configuration options to use for this operation.
* @return {Cipher} A cipher instance.
* @example
* var cipher = DES3.createDecryptor(keyWordArray, { iv: ivWordArray });
*/
static createDecryptor(key, props) {
props = typeof props === "undefined" ? {} : props;
return new DES3(Object.assign(Object.assign({}, props), { key, transformMode: Cipher.DEC_TRANSFORM_MODE }));
}
/**
* Encrypt a message with key
*
* @param {Word32Array|string} message
* @param {Word32Array|string} key
* @param {Partial<AESProps>?} props
* @example
* var encryptedMessage = DES3.encrypt("test", "pass");
*/
static encrypt(message, key, props) {
if (typeof key === "string") {
return PasswordBasedCipher.encrypt(DES3, message, key, props);
}
return SerializableCipher.encrypt(DES3, message, key, props);
}
/**
* Encrypt a encrypted message with key
*
* @param {CipherParams} cipherText
* @param {Word32Array|string} key
* @param {Partial<AESProps>?} props
* @example
* var encryptedMessage = DES3.decrypt(cipherProps, "pass");
*/
static decrypt(cipherText, key, props) {
if (typeof key === "string") {
return PasswordBasedCipher.decrypt(DES3, cipherText, key, props);
}
return SerializableCipher.decrypt(DES3, cipherText, key, props);
}
}
DES3.keySize = 192 / 32;
DES3.ivSize = 64 / 32;