使用crypto js AES ECB算法在JavaScript中加密字节数组

使用crypto js AES ECB算法在JavaScript中加密字节数组,javascript,arrays,react-native,encryption,iot,Javascript,Arrays,React Native,Encryption,Iot,我正在使用react本机应用程序与我的MIB和3通信,其身份验证过程的一部分是使用AES/ECB/NoPadding算法加密字节数组。我目前正在使用 由于我不熟悉物联网和加密,我认为这是不正确的,因为在写入MIB3和加密字节数组之后,我没有得到正确的身份验证 目前,最后一步如下所示: const base_key = [0x01,0x23,0x45,0x67,0x89,0x01,0x22,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x90,0x02] console.

我正在使用react本机应用程序与我的MIB和3通信,其身份验证过程的一部分是使用AES/ECB/NoPadding算法加密字节数组。我目前正在使用

由于我不熟悉物联网和加密,我认为这是不正确的,因为在写入MIB3和加密字节数组之后,我没有得到正确的身份验证

目前,最后一步如下所示:

const base_key = [0x01,0x23,0x45,0x67,0x89,0x01,0x22,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x90,0x02]
console.warn('Getting random number...')
const random_number = bytesToString(notification.filter((byte, index) => index > 3))

// Encrypting the key
const key = bytesToString(base_key)
const cipher = CryptoJS.AES.encrypt(random_number,key).toString()

// Step 5) Sending encrypted random number
console.warn('sending encrypted random number...')
const request_send_encrypted_key = [0x03,0x00, ...stringToBytes(cipher)]
await BleManager.writeWithoutResponse(miband3, service_uuid, characteristic_uuid, request_send_encrypted_key)
通知被过滤,因为前3个字节用于告诉正在发生的通知,所以我不需要它们

我必须将以下内容发送到MIB和3,以便正确进行身份验证:

const byteArrayToSend = [0x03,0x00, ...encryptedByteArray]
encryptedByteArray是从miband通知返回并正确加密的随机数(没有前3个字节)

我在代码中使用了“crypto js”


如何使用AES算法正确加密此bytearray以发送它?

使用
CryptoJS
进行AES加密时,必须考虑以下事项:

  • 在发布的代码中,要加密的密钥和数据(
    random_number
    )显然被指定为数组。使用
    WordArray
    -对象,因此需要进行转换
    WordArray
    -使用函数和
    CryptoJS
    -可以轻松地将对象通过十六进制字符串转换为数组,反之亦然。另一种可能性是使用函数(未测试)进行直接转换

  • 由于数组包含任意字节序列(从某种意义上说,它们通常不对应于任何可读字符),因此这里只能使用合适的编码(Base64或十六进制)。没有发布通过TestOstring和stringToBytes的
    方法,因此不清楚是否存在问题
    CryptoJS
    允许以字符串或
    WordArray
    的形式传递数据,后者用于以下情况

  • 如果
    CryptoJS.AES.encrypt
    中的第二个参数作为字符串传递,它将被解释为根据定义的算法生成实际密钥的密码短语。如果要将第二个参数解释为键(在中似乎是这样),则必须将其作为
    WordArray
    传递

  • AES/ECB/NoPadding
    用于根据链接的密码进行加密。禁用填充只能是因为要加密的数据(
    random_number
    ,根据文章,长度为16字节)对应于AES块大小(16字节)的整数倍(如果不是这种情况,则必须强制填充)

  • 加密的结果是一个
    CipherParams
    -对象,其
    ciphertext
    -属性将加密数据作为
    WordArray

考虑到这些要点,可以按如下方式执行加密:

var CryptoJS = require("crypto-js");

// Key and random number as arrays, e.g.:
var random_numberBA = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f];
var keyBA = [0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x22, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, 0x90, 0x02];

// Conversion to WordArrays
var random_numberWA = CryptoJS.enc.Hex.parse(bytesToHex(random_numberBA));
var keyWA = CryptoJS.enc.Hex.parse(bytesToHex(keyBA));

// Encryption
// - random_number as WordArray
// - Key as WordArray
// - ECB-Mode (default: CBC), No-Padding (default: Pkcs7-Padding)
var encryptedCP = CryptoJS.AES.encrypt(random_numberWA, keyWA, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding });

// Encrypted data as WordArray
var encryptedWA = encryptedCP.ciphertext;

// Conversion to array
var encryptedBA = hexToBytes(CryptoJS.enc.Hex.stringify(encryptedWA));

// Consume encryptedBA 
// ...

// Helper: from https://stackoverflow.com/a/34356351/9014097
function hexToBytes(hex) {
    for (var bytes = [], c = 0; c < hex.length; c += 2)
        bytes.push(parseInt(hex.substr(c, 2), 16));
    return bytes;
}

function bytesToHex(bytes) {
    for (var hex = [], i = 0; i < bytes.length; i++) {
        var current = bytes[i] < 0 ? bytes[i] + 256 : bytes[i];
        hex.push((current >>> 4).toString(16));
        hex.push((current & 0xF).toString(16));
    }
    return hex.join("");
}
var CryptoJS=require(“CryptoJS”);
//键和随机数作为数组,例如:
var random_numberBA=[0x00、0x01、0x02、0x03、0x04、0x05、0x06、0x07、0x08、0x09、0x0a、0x0b、0x0c、0x0d、0x0e、0x0f];
var keyBA=[0x01、0x23、0x45、0x67、0x89、0x01、0x22、0x23、0x34、0x45、0x56、0x67、0x78、0x89、0x90、0x02];
//转换为字数组
var random_numberWA=CryptoJS.enc.Hex.parse(bytesToHex(random_numberBA));
var-keyWA=CryptoJS.enc.Hex.parse(bytesToHex(keyBA));
//加密
//-随机数作为字数组
//-关键字作为字数组
//-ECB模式(默认值:CBC),无填充(默认值:Pkcs7填充)
var encryptedCP=CryptoJS.AES.encrypt(random_numberWA,keyWA,{mode:CryptoJS.mode.ECB,padding:CryptoJS.pad.NoPadding});
//加密数据作为字数组
var encryptedWA=encryptedCP.ciphertext;
//转换为数组
var encryptedBA=hexToBytes(CryptoJS.enc.Hex.stringify(encryptedWA));
//使用加密BA
// ...
//助手:从https://stackoverflow.com/a/34356351/9014097
函数hexToBytes(十六进制){
对于(变量字节=[],c=0;c>>4.toString(16));
十六进制推力((当前和0xF).toString(16));
}
返回十六进制连接(“”);
}

可以验证结果,例如..

大尖端。你能举个例子说明我们如何用这些方法解密吗?我们应该在解密方法中使用encryptedCP result还是encryptedBA?在信息如此之少的情况下,很难回答一个问题(您的解密库/方法是什么,您使用什么类型的数据,数据是如何加密的?等等)。您可以找到CryptoJS的一个很好的解释(如果要使用的话)。试着自己实现解密部分,当你陷入困境时,用你的代码和必要的信息发布一个问题。谢谢