Библиотека CryptoJS построена как модульная система, в которой каждый
криптографический примитив реализуется через единый набор базовых
абстракций: WordArray, Base,
BufferedBlockAlgorithm, Hasher,
Cipher, BlockCipher,
StreamCipher. Такая структура позволяет подключать
сторонние алгоритмы без изменения ядра библиотеки.
Все расширения регистрируются в пространстве имён
CryptoJS.algo, а их поведение определяется через
наследование базовых классов.
Основной контейнер данных, используемый во всех алгоритмах:
const data = CryptoJS.enc.Utf8.parse("test");
Структура хранит массив 32-битных слов и длину в байтах. Любой сторонний алгоритм работает именно с этим форматом.
Корневой класс для всех компонентов библиотеки:
extendconst CustomAlgo = CryptoJS.lib.Base.extend({
init: function () {
this.state = 0;
}
});
Абстракция для криптографических хеш-функций:
Структура стороннего хеша строится на переопределении методов
_doReset, _doProcessBlock,
_doFinalize.
Кастомный алгоритм хеширования определяется через наследование
CryptoJS.algo.SHA256 или
CryptoJS.lib.Hasher.
const CustomHash = CryptoJS.lib.Hasher.extend({
_doReset: function () {
this._state = 0;
},
_doProcessBlock: function (words, offset) {
for (let i = 0; i < 16; i++) {
this._state ^= words[offset + i];
}
},
_doFinalize: function () {
const result = CryptoJS.lib.WordArray.create();
result.words[0] = this._state;
result.sigBytes = 4;
return result;
}
});
CryptoJS.algo.CustomHash = CustomHash;
Использование происходит через стандартный интерфейс:
const hash = CryptoJS.algo.CustomHash.create();
hash.update("data");
const result = hash.finalize();
Режимы шифрования реализуются через CryptoJS.mode.
Базовый класс:
CryptoJS.lib.BlockCipherModeCryptoJS.lib.BlockCipherMode.EncryptorCryptoJS.lib.BlockCipherMode.Decryptorconst CustomMode = CryptoJS.lib.BlockCipherMode.extend({
Encryptor: CryptoJS.lib.BlockCipherMode.Encryptor.extend({
processBlock: function (words, offset) {
this._cipher.encryptBlock(words, offset);
}
}),
Decryptor: CryptoJS.lib.BlockCipherMode.Decryptor.extend({
processBlock: function (words, offset) {
this._cipher.decryptBlock(words, offset);
}
})
});
Регистрация:
CryptoJS.mode.CustomMode = CustomMode;
Блочные шифры наследуются от
CryptoJS.lib.BlockCipher.
_doReset — инициализация ключа_encryptBlock — шифрование блока_decryptBlock — расшифрование блока_doFinalize — финальная обработкаconst CustomCipher = CryptoJS.lib.BlockCipher.extend({
_doReset: function () {
this._subKey = this.key.words[0];
},
_encryptBlock: function (words, offset) {
words[offset] ^= this._subKey;
words[offset + 1] ^= this._subKey;
},
_decryptBlock: function (words, offset) {
words[offset] ^= this._subKey;
words[offset + 1] ^= this._subKey;
}
});
Регистрация:
CryptoJS.algo.CustomCipher = CustomCipher;
Паддинг реализуется через CryptoJS.pad.
Стандартный интерфейс:
padunpadconst CustomPad = {
pad: function (data, blockSize) {
const padding = blockSize - (data.sigBytes % blockSize);
for (let i = 0; i < padding; i++) {
data.words.push(padding);
}
data.sigBytes += padding;
},
unpad: function (data) {
const padding = data.words[data.sigBytes - 1];
data.sigBytes -= padding;
}
};
Регистрация:
CryptoJS.pad.CustomPad = CustomPad;
KDF (Key Derivation Function) подключаются через
CryptoJS.algo.
Основная структура:
const CustomKDF = CryptoJS.algo.EvpKDF.extend({
cfg: CryptoJS.algo.EvpKDF.cfg.extend({
keySize: 4,
iterations: 1
}),
compute: function (password, salt) {
const result = CryptoJS.lib.WordArray.create();
result.words[0] = password.words[0] ^ salt.words[0];
result.sigBytes = 16;
return result;
}
});
Регистрация:
CryptoJS.algo.CustomKDF = CustomKDF;
Все подключаемые алгоритмы фиксируются в одном реестре:
CryptoJS.algo — хеши и ключевые функцииCryptoJS.mode — режимы шифрованияCryptoJS.pad — схемы дополненияCryptoJS.format — форматы сериализацииСтруктура расширения всегда предполагает явное добавление:
CryptoJS.algo.MyAlgorithm = MyAlgorithm;
Результат работы криптографических операций инкапсулируется в
CipherParams:
ciphertextkeyivsaltПодключаемые алгоритмы автоматически используют эту структуру при
вызове encrypt и decrypt.
Сторонние реализации часто поставляются как отдельные файлы:
Типичная схема интеграции:
(function (CryptoJS) {
const ExternalAlgo = CryptoJS.algo.Base.extend({
process: function () {}
});
CryptoJS.algo.ExternalAlgo = ExternalAlgo;
})(CryptoJS);
При подключении сторонних реализаций учитываются внутренние ограничения:
WordArrayBlockCipher_doProcessBlock для хешейBufferedBlockAlgorithm для потоковой
обработкиCryptoJS поддерживает композицию:
Структура вызова:
CryptoJS.AES.encrypt(data, key, {
mode: CryptoJS.mode.CustomMode,
padding: CryptoJS.pad.CustomPad
});
Каждый компонент может быть заменён внешней реализацией без изменения ядра библиотеки.