find a solution:
- when decrypt the ticketKey, use aes-256-ecb and the full "Access Secret/Client Secret" as key,
- convert the decipher to utf-8 which is 16 bytes and can be used to encrypt the Temporary Password but use aes-128-ecb instead
Here is my code:
// Decrypt the temporary ticketKey,
const decryptTicketKey = (encryptedKey, TUYA_SECRET_KEY) => {
try {
const decipher = crypto.createDecipheriv('aes-256-ecb', Buffer.from(TUYA_SECRET_KEY, 'utf8'), null);
decipher.setAutoPadding(true);
const decrypted = Buffer.concat([decipher.update(Buffer.from(encryptedKey, 'hex')), decipher.final()]);
// console.log('ticketKey Length (HEX):', encryptedKey.length); // Check the length of encryptedKey
console.log('decrypted Key Length (HEX):', decrypted.length); // Check the length
Code: Select all
const utf8Key = decrypted.toString('utf8');
console.log('decrypted Key converted back to utf8, not the Binary in buffer:', utf8Key);
return utf8Key;
} catch (error) {
console.error('Error decrypting ticketKey:', error.message);
throw error;
}
};
// Set a temporary password for the Tuya device
const setTemporaryPassword = async ({ deviceId, name, password, effectiveTime, invalidTime }) => {
try {
// Fetch the temporary ticket
const ticket = await fetchTemporaryKey(deviceId);
const decryptedKey = decryptTicketKey(ticket.ticket_key, TUYA_SECRET_KEY);
// Encrypt the password using the decrypted ticket key
const cipher = crypto.createCipheriv(
'aes-128-ecb',
Buffer.from(decryptedKey, 'utf8'), // Ensure decryptedKey
is treated as 16 bytes binary
null
);
cipher.setAutoPadding(true);
const encryptedPassword = Buffer.concat([
cipher.update(Buffer.from(password, 'utf8')),
cipher.final()
]).toString('hex');
// Prepare the schedule_list (example values, adjust as needed)
const scheduleList = [
{
effective_time: 0, // Example: 0:00 (in minutes)
invalid_time: 1440, // Example: 24:00 (in minutes)
working_day: 0 // Example: All days (or specify specific days as required)
}
];
console.log('Request Payload:', {
name: name,
password: encryptedPassword,
effective_time: effectiveTime,
invalid_time: invalidTime,
password_type: 'ticket',
ticket_id: ticket.ticket_id,
effective_time: effectiveTime,
invalid_time: invalidTime,
schedule_list: scheduleList,
});
// Send the request to Tuya
const response = await tuya.request({
method: 'POST',
path: /v1.0/devices/${deviceId}/door-lock/temp-password
,
body: {
name: name,
password: encryptedPassword,
effective_time: effectiveTime,
invalid_time: invalidTime,
password_type: 'ticket',
ticket_id: ticket.ticket_id,
schedule_list: scheduleList, // Include schedule_list in the payload
},
});
Code: Select all
if (response.success) {
console.log(`Temporary password set successfully for device ${deviceId}`);
console.log(response.result.id);
return response.result;
} else {
throw new Error(`Failed to set temporary password: ${response.msg}`);
}
} catch (error) {
console.error(Error setting temporary password for device ${deviceId}:
, error.message);
throw error;
}
};