Перенос JavaScript для библиотеки aesjs в библиотеку CryptoJS - PullRequest
1 голос
/ 23 декабря 2019

У меня есть фрагмент кода, который был написан для библиотеки aesjs (https://github.com/ricmoo/aes-js/blob/master/index.js). Серверу отправляется запрос с зашифрованным токеном AES на основе статических строк Base64 (данные, ключ данных, iv) с текущимвременная метка, добавленная к данным. Вот код для использования библиотеки aesjs:

function base64ToByteArray(base64String){try{var sliceSize=1024;var byteCharacters=window.atob(base64String);var bytesLength=byteCharacters.length;var slicesCount=Math.ceil(bytesLength/sliceSize);var byteArrays=new Array(slicesCount);for(var sliceIndex=0;sliceIndex<slicesCount;++sliceIndex){var begin=sliceIndex*sliceSize;var end=Math.min(begin+sliceSize,bytesLength);var bytes=new Array(end-begin);for(var offset=begin,i=0;offset<end;++i,++offset){bytes[i]=byteCharacters[offset].charCodeAt(0);}byteArrays[sliceIndex]=new Uint8Array(bytes);}return byteArrays;}catch(e){api.info("Couldn't convert to byte array: "+e);return undefined;}}

var msg = 'ZuwnEFQ7gTbtfEH5rz9ZOh/zV2LplPscMl2qLnV9gOU';
var dataKey = 'REXGk/8fpOQSoCXWIGZk2g';
var delimiter = '|';
var iv = 'KCgWOBhGET1aIRMiFcIw';
iv = new Uint8Array(aesjs.utils.utf8.toBytes(atob(iv)));
// Set timestamp
timestamp = getTimestamp();  // returns string of format: 2019-12-23T05:11:35Z
// Start encrypting!
var data1 = msg + delimiter + timestamp;
var data_bytes1 = aesjs.utils.utf8.toBytes(data1);
var data_bytes_padded1 = aesjs.padding.pkcs7.pad(data_bytes1);
var dKeyStr = base64ToByteArray(dataKey)[0];
aesCbc = new aesjs.ModeOfOperation.cbc(dKeyStr, iv);
encryptedBytes1 = aesCbc.encrypt(data_bytes_padded1);
var encryptedString1 = btoa(String.fromCharCode.apply(null, encryptedBytes1));
// LvmLYbp0a1M4XUdPWXO5y3Ntn/+UMqibzrIrfGG5Ctlbf2zI+YGF6ipp+TAdEZkMrBwbl/AnWHA32c43slNgs+673ar3MsT7HWgZLhQVftg=

Код для CryptoJS, конечно, должен немного отличаться, но я получаю неправильный encryptedString1 (сервержалуется на это). Может кто-нибудь сказать мне, что я делаю не так? CryptoJS код:

function byteArrayToWordArray(ba){var wa=[],i;for(i=0;i<ba.length;i++){wa[(i/4)|0]|=ba[i]<<(24-8*i);}return CryptoJS.lib.WordArray.create(wa,ba.length);}
var msg = 'ZuwnEFQ7gTbtfEH5rz9ZOh/zV2LplPscMl2qLnV9gOU';
var dataKey = 'REXGk/8fpOQSoCXWIGZk2g';
var delimiter = '|';
var iv = 'KCgWOBhGET1aIRMiFcIw';
iv = CryptoJS.enc.Base64.parse(iv);
// Set timestamp
timestamp = getTimestamp();  // returns string of format: 2019-12-23T05:11:35Z
// Start encrypting!
data1 = givenReqId + delimiter + timestamp;
dataKey = CryptoJS.enc.Base64.parse(dataKey);
encrypted1 = CryptoJS.AES.encrypt(data1, dataKey, {iv: iv});
encrypted1 = encrypted1.toString();
// u0q0/g6w1lWwRyPKjbmr0BCGlN0po9y1djotJqY2IAB5yNVXih1bw7z6cyNP0d1duTRarsahEudeDkvTOzotL4egKsk8Il7Y/c0E6NuEK8Q=

1 Ответ

0 голосов
/ 24 декабря 2019

IV, закодированный Base64, используемый в обоих кодах:

KCgWOBhGET1aIRMiFcIw

дает декодированный код:

28 28 16 38 18 46 11 3d 5a 21 13 22 15 c2 30

, т. Е. IV имеет длину 15 байтов и поэтому слишком короткий, что можетлегко проверить в Интернете, например, здесь . Однако код aes-js выполняет декодирование некорректно и предоставляет 16-байтовый IV:

28 28 16 38 18 46 11 3d 5a 21 13 22 15 c3 82 30

, т. Е. Ошибка декодирования является причиной того, что IV, который на самом деле слишком короткий, получает правильную длину. Напротив, код CryptoJS выполняет декодирование правильно, а затем неявно дополняет слишком короткий IV с 0 байтами до длины 16 байтов:

28 28 16 38 18 46 11 3d 5a 21 13 22 15 c2 30 00

Таким образом, оба кода используют разные IV, что приводит к разным шифротекстам,Неправильное декодирование в коде aes-js происходит в строке:

iv = new Uint8Array(aesjs.utils.utf8.toBytes(atob(iv)));

, которая должна быть заменена на

var iv = base64ToByteArray(iv)[0];

, аналогично ключу. И, конечно, необходимо использовать IV правильной длины, то есть 16 байтов, в противном случае код aes-js отобразит соответствующее сообщение об ошибке. Затем aes-js и код CryptoJS создают один и тот же зашифрованный текст.

...