Secure a byte array in JavaScript by utilizing the crypto js AES ECB algorithm

As I navigate through the world of IoT and encryption, I find myself encountering a challenge with my React Native app that communicates with my MiBand 3. As part of the authentication process, I need to encrypt an array of bytes using the AES/ECB/NoPadding algorithm. To guide me, I have been referring to this code provided by Yogesh Ojha.

However, despite following the steps outlined in the reference code, I suspect that the final step of authentication might be incorrect. After transmitting the encrypted byte array to the MiBand 3, I am facing authentication issues.

The current implementation of the last step involves:

const base_key = [0x01,0x23,0x45,0x67,0x89,0x01,0x22,0x23,0x34,0x45,0x56,0x67,0x78,0x89,0x90,0x02]
console.warn('Obtaining 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) Transmitting encrypted random number
console.warn('Transmitting encrypted random number...')
const request_send_encrypted_key = [0x03,0x00, ...stringToBytes(cipher)]
await BleManager.writeWithoutResponse(miband3, service_uuid, characteristic_uuid, request_send_encrypted_key)

The notification data is filtered because the first 3 bytes indicate the type of notification, which are unnecessary for the encryption process.

To authenticate successfully, I must send the following to the MiBand 3:

const byteArrayToSend = [0x03,0x00, ...encryptedByteArray]

The encryptedByteArray should contain the properly encrypted random number retrieved from the MiBand notification (excluding the first 3 bytes).

In my code, I am utilizing 'crypto-js' library along with 'react-native-ble-manager'. However, I am struggling to implement the AES encryption correctly for sending the bytearray. Can anyone guide me on how to achieve this?

Answer №1

When using CryptoJS for AES encryption, there are several important considerations to keep in mind:

  • In the provided code snippet, keys and data intended for encryption (random_number) are explicitly designated as arrays. However, CryptoJS utilizes WordArray objects, necessitating a conversion. This can be achieved by easily converting WordArray objects into arrays through hexadecimal strings and vice versa using the provided functions and the CryptoJS Encoders. Alternatively, direct conversion can also be carried out using these functions.

  • Since the arrays contain arbitrary byte sequences (often not corresponding to readable characters), only suitable encodings such as Base64 or hexadecimal should be used. While it's unclear whether the methods bytesToString and stringToBytes pose any issues as they were not included in the excerpt, CryptoJS enables passing data as either a string or a WordArray, with the latter being employed subsequently.

  • Notably, if the second parameter in CryptoJS.AES.encrypt is passed as a string, it serves as a passphrase that generates the actual key via a defined algorithm, detailed here. Conversely, when this parameter is interpreted as a key (as evident in the reference code), it must be presented as a WordArray.

  • The chosen method for encryption is AES/ECB/NoPadding, as specified in the associated Medium article. The absence of padding is permissible due to the encrypted data's length aligning with integer multiples of the AES block size (16 bytes). Should this not hold true, padding would be obligatory.

  • Following encryption, the output comprises a CipherParams object whereby the encrypted data appears as a WordArray, outlined here.

For successful encryption implementation, the following steps need to be followed:

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));

// Utilize encryptedBA 
// ...

// Helper function 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("");
}

To verify the result, please visit this link.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to store the output of a <script src> tag into a variable

How can I retrieve the output of a file in JavaScript? I am looking to achieve: var list = <script src="src/users.json"></script> Is it feasible to accomplish this using JavaScript? ...

Unable to create a flawless circle using Canvas

No matter how hard I try, drawing a perfect circle seems impossible for me. Every time I attempt it, all I manage to create is an ellipse. Check out this code snippet I put together as an example: function canvasClicked(number) { var c = "canvas" + nu ...

Requesting the user to repeatedly input their birth year until it is less than the current year

Can anyone help me figure out how to display a prompt until the user enters a birth year that is less than the current year? I've tried using a loop in my code, but I'm having trouble getting it right. Any assistance would be greatly appreciated. ...

The JQuery Ajax call returned with a status of 0 and an empty ResponseText

Here is the ajax request I am using: $.ajax({ type: "POST", url: "https://forlineplus.forsa.com.co/projects/validar-redireccion-sio?fup=" + idFup, //contentType: "application/json; charset=utf-8", ...

Script designed to track modifications on a specific webpage

Attempting to purchase items online has become a frustrating challenge as stock seems to disappear within minutes of being added :/ I am currently working on creating a custom grease/tampermonkey script to monitor the page and notify me when products beco ...

Converting JSON object to a string

I have an object that contains the value "error" that I need to extract. [{"name":"Whats up","error":"Your name required!"}] The inspector displays the object in this format: [Object] 0: Object error: "Your name required!" name ...

What are the steps to utilize fullcalendar events as variables in your code?

Hey there! I am currently using fullcalendar and I'm looking to define event.start and event.end as variables so that I can utilize them within my PHP code, similar to the following: $sql = "SELECT * FROM chambre WHERE id NOT IN (SE ...

Java function to determine if each piece is on a different diagonal

I am currently developing a program to generate solutions for the n-queens problem, specifically for all cases where 1 <= n <= 13. The program will take an integer input n from the user to determine the size of the Queens problem to be solved. For in ...

d3.on event firing prior to mouseover event

This page showcases a dynamic d3 bar chart. On line 162, we have an interesting event listener that logs a message when the user hovers over a bar on the chart. However, the log is displayed as soon as the page loads. You can see the running code in actio ...

Is there a beginner's pack or trial version available for utilizing TypeScript with IBM Cloud Functions / OpenWhisk?

While working on developing actions in IBM Cloud Functions, I have been primarily using Node.js / Javascript and Python for coding. However, I haven't come across specific instructions on how to incorporate TypeScript into IBM Cloud Functions. I am c ...

Determining the selected section in Swift: A guide

I have been working on a dynamic tableView that displays a large number of items, categorized into sections based on the client's selection. Each section represents a client name and the rows within each section represent the foods selected by the cli ...

Node.js is having trouble locating a module that has been installed

Upon transferring my node.js application to a different PC (where it functioned flawlessly on the development machine) and manually installing all the necessary dependencies, I encountered an error when attempting to run it: C:\Users\myself>n ...

Attempting to display the contents of an array by iterating through it with a loop in a Angular JS using Javascript

I am attempting to display each item in an array that is a part of an object's property: { position: "Finance Office Assistant", employer: "Washtenaw County Finance Department", location: "Ann Arbor, MI", start_date: " ...

What steps should I take to generate a stylized date input in javascript?

Looking to dynamically create a date string in JavaScript with the following format: dd-MMM-yyyy Need the dd part to change between 1 and 29 each time I generate the variable within a loop Month (MMM) should be set as Jan ...

Is it possible to modify the background-color of a minified gallery using CSS in jQuery?

As I was brainstorming ideas for my website, I thought about the possibility of creating a small preview gallery for background images. The goal would be to allow users to hover over an image in the gallery and have the CSS background image of the site cha ...

What are the steps to setting up an intelligent LAN or corporate npm registry for storing node.js packages?

Is it possible to set up a smart local network or company npm registry for node.js packages? This registry should act as a proxy, fetching only the necessary packages when needed, rather than simply mirroring the main registry. This concept is similar to ...

To reveal truncated words one at a time for each item, simply hover your mouse over the text field to see the complete text appear

The content on the pages can be partially displayed by unfolding or closing the remaining content in html/JS through this link (the page already has an unfold or close function in a box). Now, I want to display the partial titles of the contents in the box ...

Having difficulty with the javascript click() function in an html document

Thank you in advance for checking this out. In my web application, users can choose options from four separate drop-down menus. Once a selection is made, the software triggers a click() function that generates a new span element within a div: var activeF ...

Issue with Google Script not initializing in a second form

I'm currently working on a project that is bound to a Google Sheet container. The purpose of this project is to search for a specific value in one column, and based on the result, either mark the record as complete, allow for missing values to be fill ...

Fetching data using ajax and then appending it to the webpage

I am currently loading content from a PHP file in JSON format. products.php <?php $stmt = $mysqli->prepare("SELECT * FROM products LIMIT 10"); $stmt->execute(); $products = $stmt->get_result(); $produc ...