fix: 增加获取设备公钥、私钥接口

This commit is contained in:
liyi 2025-09-08 17:14:15 +08:00
parent a3ad89d0d4
commit ac1e447eca
7 changed files with 57 additions and 36 deletions

View File

@ -5,7 +5,9 @@ import 'package:starwork_flutter/base/app_logger.dart';
import 'package:starwork_flutter/ble/ble_config.dart'; import 'package:starwork_flutter/ble/ble_config.dart';
import 'package:starwork_flutter/ble/command/base/base_ble_command.dart'; import 'package:starwork_flutter/ble/command/base/base_ble_command.dart';
import 'package:starwork_flutter/ble/command/ble_command_manager.dart'; import 'package:starwork_flutter/ble/command/ble_command_manager.dart';
import 'package:starwork_flutter/ble/command/request/ble_cmd_get_private_key.dart';
import 'package:starwork_flutter/ble/command/request/ble_cmd_get_public_key.dart'; import 'package:starwork_flutter/ble/command/request/ble_cmd_get_public_key.dart';
import 'package:starwork_flutter/ble/command/response/ble_cmd_get_private_key_parser.dart';
import 'package:starwork_flutter/ble/command/response/ble_cmd_get_public_key_parser.dart'; import 'package:starwork_flutter/ble/command/response/ble_cmd_get_public_key_parser.dart';
import 'package:starwork_flutter/ble/model/scan_device_info.dart'; import 'package:starwork_flutter/ble/model/scan_device_info.dart';
import 'package:starwork_flutter/common/constant/device_type.dart'; import 'package:starwork_flutter/common/constant/device_type.dart';
@ -104,6 +106,9 @@ class BleService {
/// ///
bool get isScanningNow => FlutterBluePlus.isScanningNow; bool get isScanningNow => FlutterBluePlus.isScanningNow;
///
BluetoothDevice? get connectedDevice => _connectedDevice;
/// ///
Future<void> _initialize() async { Future<void> _initialize() async {
AppLogger.highlight('🚀 BleService 正在初始化...'); AppLogger.highlight('🚀 BleService 正在初始化...');
@ -286,11 +291,6 @@ class BleService {
if (result != null) { if (result != null) {
// //
_triggerCommandResponseWaiters(result); _triggerCommandResponseWaiters(result);
//
// if (result is GetPublicKeyResponse) {
// GetPublicKeyResponse response = result;
// }
} else { } else {
AppLogger.warn('⚠️ 数据包解析失败或不匹配任何命令'); AppLogger.warn('⚠️ 数据包解析失败或不匹配任何命令');
} }
@ -303,9 +303,6 @@ class BleService {
void _triggerCommandResponseWaiters(dynamic response) { void _triggerCommandResponseWaiters(dynamic response) {
// //
List<String> completedKeys = []; List<String> completedKeys = [];
// GetPublicKeyResponse类型ID进行匹配
int commandId = response.commandId; int commandId = response.commandId;
String? commandKey = _commandIdToKeyMap[commandId]; String? commandKey = _commandIdToKeyMap[commandId];
@ -378,17 +375,7 @@ class BleService {
_commandResponseWaiters[commandKey] = responseCompleter; _commandResponseWaiters[commandKey] = responseCompleter;
// 5. cmdId静态字段 // 5. cmdId静态字段
try { _registerCommandId(command, commandKey);
// cmdId字段
if (command is BleCmdGetPublicKey) {
int commandId = BleCmdGetPublicKey.cmdId;
_commandIdToKeyMap[commandId] = commandKey;
AppLogger.debug('📝 命令ID映射: 0x${commandId.toRadixString(16).padLeft(4, '0')} -> $commandKey');
}
//
} catch (e) {
AppLogger.warn('⚠️ 无法获取命令ID: $e');
}
// 6. // 6.
Timer timeoutTimer = Timer(timeout, () { Timer timeoutTimer = Timer(timeout, () {
@ -425,6 +412,30 @@ class BleService {
} }
} }
/// commandKey cmdId
void _registerCommandId(dynamic command, String commandKey) {
try {
final int? commandId = switch (command) {
BleCmdGetPublicKey() => BleCmdGetPublicKey.cmdId,
BleCmdGetPrivateKey() => BleCmdGetPrivateKey.cmdId,
//
// BleCmdAnother() => BleCmdAnother.cmdId,
_ => null, //
};
if (commandId != null) {
_commandIdToKeyMap[commandId] = commandKey;
AppLogger.debug(
'📝 命令ID映射: 0x${commandId.toRadixString(16).padLeft(4, '0')} -> $commandKey',
);
} else {
AppLogger.debug('❓ 未知命令类型,无法注册 commandId: $commandKey');
}
} catch (e) {
AppLogger.warn('⚠️ 无法获取命令ID: $e');
}
}
void cancel() { void cancel() {
/// ///
_adapterStateSubscription?.cancel(); _adapterStateSubscription?.cancel();

View File

@ -145,9 +145,11 @@ class BleCommandManager {
return _decryptAES128(parsedPacket.data); return _decryptAES128(parsedPacket.data);
case BaseBleCommand.ENCRYPT_TYPE_SM4_PRESET: case BaseBleCommand.ENCRYPT_TYPE_SM4_PRESET:
var connectedDevice = BleService().connectedDevice;
var platformName = connectedDevice?.platformName;
var decrypt = SM4.decrypt( var decrypt = SM4.decrypt(
parsedPacket.data, parsedPacket.data,
key: utf8.encode('TMH_190068d76ae8'), key: utf8.encode(platformName!),
mode: SM4CryptoMode.ECB, mode: SM4CryptoMode.ECB,
); );
return decrypt; return decrypt;

View File

@ -126,15 +126,12 @@ class BleCmdGetPrivateKey extends BaseBleCommand<GetPrivateKeyResponse> {
data.addAll(utf8.encode(keyId)); data.addAll(utf8.encode(keyId));
data = getFixedLengthList(data, 40 - keyIDLength); data = getFixedLengthList(data, 40 - keyIDLength);
//authUserID 40 //authUserID 20
final int authUserIDLength = utf8.encode(authUserID!).length; final int authUserIDLength = utf8.encode(authUserID!).length;
data.addAll(utf8.encode(authUserID)); data.addAll(utf8.encode(authUserID));
data = getFixedLengthList(data, 20 - authUserIDLength); data = getFixedLengthList(data, 20 - authUserIDLength);
//NowTime 4 //NowTime 4
// DateTime now = DateTime.now();
// int timestamp = now.millisecondsSinceEpoch;
// var d1 = 0x11223344;
data.add((nowTime & 0xff000000) >> 24); data.add((nowTime & 0xff000000) >> 24);
data.add((nowTime & 0xff0000) >> 16); data.add((nowTime & 0xff0000) >> 16);
data.add((nowTime & 0xff00) >> 8); data.add((nowTime & 0xff00) >> 8);
@ -149,9 +146,6 @@ class BleCmdGetPrivateKey extends BaseBleCommand<GetPrivateKeyResponse> {
authCodeData.addAll(utf8.encode(keyId!)); authCodeData.addAll(utf8.encode(keyId!));
//NowTime 4 //NowTime 4
// DateTime now = DateTime.now();
// int timestamp = now.millisecondsSinceEpoch;
// var d1 = 0x11223344;
authCodeData.add((nowTime & 0xff000000) >> 24); authCodeData.add((nowTime & 0xff000000) >> 24);
authCodeData.add((nowTime & 0xff0000) >> 16); authCodeData.add((nowTime & 0xff0000) >> 16);
authCodeData.add((nowTime & 0xff00) >> 8); authCodeData.add((nowTime & 0xff00) >> 8);
@ -159,7 +153,7 @@ class BleCmdGetPrivateKey extends BaseBleCommand<GetPrivateKeyResponse> {
authCodeData.addAll(publicKey); authCodeData.addAll(publicKey);
// KeyIDauthUserIDmd5加密之后就是authCode // authUserIDKeyIDmd5加密之后就是authCode
var authCode = md5.convert(authCodeData); var authCode = md5.convert(authCodeData);
data.add(authCode.bytes.length); data.add(authCode.bytes.length);

View File

@ -65,11 +65,6 @@ class BleCmdGetPrivateKeyParser extends BaseBleResponseParser {
@override @override
GetPrivateKeyResponse parseResponse(ParsedPacket parsedPacket, List<int> rawResponseData) { GetPrivateKeyResponse parseResponse(ParsedPacket parsedPacket, List<int> rawResponseData) {
try { try {
// :
// 0-1: ID (0x3090, )
// 2: (0x00=, =)
// 3-N: ()
if (rawResponseData.length < 3) { if (rawResponseData.length < 3) {
throw ArgumentError('应答数据长度不足: ${rawResponseData.length}字节 < 3字节'); throw ArgumentError('应答数据长度不足: ${rawResponseData.length}字节 < 3字节');
} }

View File

@ -1,7 +1,9 @@
class CacheKeys { class CacheKeys {
static const String isSendValidationCode = 'isSendValidationCode'; static const String isSendValidationCode = 'isSendValidationCode';
static const String token = 'token'; static const String token = 'token';
static const String publicKeyHex = 'publicKeyHex'; static const String lockPublicKey = 'lockPublicKey';
static const String lockCommKey = 'lockCommKey';
static const String lockSignKey = 'lockSignKey';
static const String starCloudUserInfo = 'starCloudUserInfo'; static const String starCloudUserInfo = 'starCloudUserInfo';
static const String starCloudUserLoginInfo = 'starCloudUserLoginInfo'; static const String starCloudUserLoginInfo = 'starCloudUserLoginInfo';

View File

@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'dart:async'; import 'dart:async';
@ -83,4 +85,17 @@ class SharedPreferencesUtils {
static Future<bool?> getBool(String key) async { static Future<bool?> getBool(String key) async {
return _prefs?.getBool(key); return _prefs?.getBool(key);
} }
// List<int>
static Future<void> saveIntList(String key, List<int> list) async {
final base64String = base64Encode(list);
await _prefs?.setString(key, base64String);
}
// List<int>
static Future<List<int>?> getIntList(String key) async {
final base64String = _prefs?.getString(key);
if (base64String == null) return null;
return base64Decode(base64String);
}
} }

View File

@ -182,7 +182,7 @@ class SearchDeviceController extends BaseController {
); );
if (publicKeyResponse != null && publicKeyResponse.isSuccess) { if (publicKeyResponse != null && publicKeyResponse.isSuccess) {
AppLogger.info('🎯 获取公钥成功: ${publicKeyResponse.publicKeyHex}'); AppLogger.info('🎯 获取公钥成功: ${publicKeyResponse.publicKeyHex}');
SharedPreferencesUtils.setString(CacheKeys.publicKeyHex, publicKeyResponse.publicKeyHex); await SharedPreferencesUtils.saveIntList(CacheKeys.lockPublicKey, publicKeyResponse.publicKey);
BleCmdGetPrivateKey getPrivateKeyCmd = BleCmdGetPrivateKey( BleCmdGetPrivateKey getPrivateKeyCmd = BleCmdGetPrivateKey(
lockId: device.advName, lockId: device.advName,
keyId: '1', keyId: '1',
@ -201,7 +201,9 @@ class SearchDeviceController extends BaseController {
autoConnectIfNeeded: true, autoConnectIfNeeded: true,
); );
if (privateKeyResponse != null && privateKeyResponse.isSuccess) { if (privateKeyResponse != null && privateKeyResponse.isSuccess) {
AppLogger.info('🎯 获取私钥成功: ${privateKeyResponse.commKeyHex}'); await SharedPreferencesUtils.saveIntList(CacheKeys.lockCommKey, privateKeyResponse.commKey);
await SharedPreferencesUtils.saveIntList(CacheKeys.lockSignKey, privateKeyResponse.signKey);
AppLogger.info('🎯 获取私钥成功: ${privateKeyResponse.toString()}');
} }
} else { } else {
AppLogger.warn('⚠️ 命令发送完成,但未收到有效响应'); AppLogger.warn('⚠️ 命令发送完成,但未收到有效响应');