From f45258a061a87fda4a13ab14ca6536d44c87a031 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Fri, 18 Jul 2025 16:02:28 +0800 Subject: extract to signer --- packages/airmx/src/airmx.ts | 9 ++------- packages/airmx/src/util.ts | 31 ++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 8 deletions(-) (limited to 'packages') diff --git a/packages/airmx/src/airmx.ts b/packages/airmx/src/airmx.ts index 1050bf0..a507260 100644 --- a/packages/airmx/src/airmx.ts +++ b/packages/airmx/src/airmx.ts @@ -1,4 +1,3 @@ -import crypto from 'crypto' import { MqttClient } from 'mqtt' import type { @@ -138,12 +137,8 @@ export class Airmx { #validateMessage(deviceId: number, message: string, sig: string) { const device = this.#getDevice(deviceId) - const plainText = message.slice(1, message.lastIndexOf('"sig"')) - const calculated = crypto - .createHash('md5') - .update(plainText) - .update(device.key) - .digest('hex') + const plainText = message.slice(1, message.lastIndexOf(',"sig"')) + const calculated = this.#signer.signText(plainText, device.key) if (calculated !== sig) { throw new Error('Failed to validate the message.') } diff --git a/packages/airmx/src/util.ts b/packages/airmx/src/util.ts index 496ae56..b5cbd4b 100644 --- a/packages/airmx/src/util.ts +++ b/packages/airmx/src/util.ts @@ -2,11 +2,40 @@ import crypto from 'crypto' import type { CommandMessage } from './messages.js' export class Signer { + /** + * Calculate the signature for the message. + * + * @param message - The command message. + * @param key - The device key. + * @returns An 8-byte signature for the given message. + */ sign(message: CommandMessage, key: string) { const plainText = JSON.stringify(message.payload()) + return this.#hash(plainText.slice(1, -1), key) + } + + /** + * Calculate the signature for the plain text. + * + * @param message - The plain text. + * @param key - The device key. + * @returns An 8-byte signature for the given text. + */ + signText(message: string, key: string) { + return this.#hash(message, key) + } + + /** + * Hash the data with the MD5 algorithm. + * + * @param data - The plain text. + * @param key - The device key. + * @returns An 8-byte signature for the given data. + */ + #hash(data: string, key: string) { return crypto .createHash('md5') - .update(plainText.slice(1, -1)) + .update(data) .update(',') .update(key) .digest('hex') -- cgit v1.2.3