将aesjs库的JavaScript迁移到CryptoJS库

问题描述 投票:1回答:1

我有一个为aesjs库(https://github.com/ricmoo/aes-js/blob/master/index.js)编写的代码段。向服务器发送的请求是基于静态Base64字符串(数据,数据密钥,iv)的AES加密令牌,并将当前时间戳添加到数据中。这是使用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=
javascript aes cryptojs
1个回答
0
投票

两个代码中使用的Base64编码的IV:

KCgWOBhGET1aIRMiFcIw

给予解码:

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

即IV的长度为15个字节,因此太短,可以很容易地在线验证,例如here。但是,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];

类似于键。当然,必须使用正确长度(即16个字节)的IV,否则aes-js代码将显示相应的错误消息。然后,aes-js和CryptoJS代码生成相同的密文。

© www.soinside.com 2019 - 2024. All rights reserved.