fix: 增加获取设备公钥、私钥接口
This commit is contained in:
parent
a3ad89d0d4
commit
ac1e447eca
@ -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();
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
// 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode
|
// 把authUserID、KeyID、时间戳、公钥通过md5加密之后就是authCode
|
||||||
var authCode = md5.convert(authCodeData);
|
var authCode = md5.convert(authCodeData);
|
||||||
|
|
||||||
data.add(authCode.bytes.length);
|
data.add(authCode.bytes.length);
|
||||||
|
|||||||
@ -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字节');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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';
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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('⚠️ 命令发送完成,但未收到有效响应');
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user