From dfc5dc433fc248e2b2097ab2c6a9f0ec113b786c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AD=8F=E5=B0=91=E9=98=B3?= <786612630@qq.com> Date: Sat, 12 Aug 2023 18:32:49 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E8=B0=83=E8=AF=95=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/blue/io_protocol/io_addUser.dart | 143 ++++++++++++++++-- .../blue/io_protocol/io_getPrivateKey.dart | 26 ++-- .../lib/blue/io_protocol/io_getPublicKey.dart | 10 +- star_lock/lib/blue/io_tool/io_tool.dart | 54 ++++--- star_lock/lib/blue/reciver_data.dart | 15 +- star_lock/lib/blue/sm4Encipher/sm4.dart | 8 +- .../lib/mine/mine/starLockMine_state.dart | 6 +- .../lib/network/request_interceptor.dart | 2 +- star_lock/lib/tools/storage.dart | 117 +++++++++++--- 9 files changed, 297 insertions(+), 84 deletions(-) diff --git a/star_lock/lib/blue/io_protocol/io_addUser.dart b/star_lock/lib/blue/io_protocol/io_addUser.dart index 17b1fa2f..88b757f2 100644 --- a/star_lock/lib/blue/io_protocol/io_addUser.dart +++ b/star_lock/lib/blue/io_protocol/io_addUser.dart @@ -1,13 +1,16 @@ +import 'dart:convert'; + import '../io_tool/io_tool.dart'; +import '../sm4Encipher/sm4.dart'; import 'io_reply.dart'; import 'io_sender.dart'; import 'io_type.dart'; +import 'package:crypto/crypto.dart' as crypto; //TODO:添加用户 class AddUserCommand extends SenderProtocol { - int? cmdID; String? lockID; String? authUserID; String? keyID; @@ -18,11 +21,10 @@ class AddUserCommand extends SenderProtocol { int? expireDate; int? role; String? password; - int? token; - int? authCodeLen; - String? authCode; + int? needAuthor; + List? userPperationToken; + List? publicKeyData; AddUserCommand({ - this.cmdID, this.lockID, this.authUserID, this.keyID, @@ -33,20 +35,133 @@ class AddUserCommand extends SenderProtocol { this.expireDate, this.role, this.password, - this.token, - this.authCodeLen, - this.authCode, + this.needAuthor, + this.userPperationToken, + this.publicKeyData }) : super(CommandType.addUser); @override List messageDetail() { List data = []; - // data.add(0x21); - // int d = direction!.toInt(); - // data.addAll(intToByte2ListHigh(d)); - // data.add(0x22); - // int s = speed!.toInt(); - // data.add(s); + List ebcData = []; + + // 指令类型 + int type = commandType!.typeValue; + double typeDouble = type / 256; + int type1 = typeDouble.toInt(); + int type2 = type % 256; + data.add(type1); + data.add(type2); + + // 锁id 40 + int lockIDLength = utf8.encode(lockID!).length; + data.addAll(utf8.encode(lockID!)); + data = getFixedLengthList(data, 40 - lockIDLength); + + //authUserID 20 + int authUserIDLength = utf8.encode(authUserID!).length; + data.addAll(utf8.encode(authUserID!)); + data = getFixedLengthList(data, 20 - authUserIDLength); + + //KeyID 40 + int keyIDLength = utf8.encode(keyID!).length; + data.addAll(utf8.encode(keyID!)); + data = getFixedLengthList(data, 40 - keyIDLength); + + //userID 要接受钥匙的用户的useid 20 + int userIDLength = utf8.encode(authUserID!).length; + data.addAll(utf8.encode(authUserID!)); + data = getFixedLengthList(data, 20 - authUserIDLength); + + // openModel + data.add(openMode!); + + // keyType + data.add(keyType!); + + int? d1, d2; + if(role == 255){ + d1 = 0;//Date.parse(new Date()) / 1000; + d2 = 0xffffffff;//d1 + 86440; + }else{ + d1 = startDate; + d2 = expireDate; + } + + // StartDate 4 + data.add((d1! & 0xff000000) >> 24); + data.add((d1 & 0xff0000) >> 16); + data.add((d1 & 0xff00) >> 8); + data.add((d1 & 0xff)); + + // expireDate 4 + data.add((d2! & 0xff000000) >> 24); + data.add((d2 & 0xff0000) >> 16); + data.add((d2 & 0xff00) >> 8); + data.add((d2 & 0xff)); + + // role 长度1 用户角色,0:普通用户,1:管理员,0xff:超级管理员 + data.add(role!); + + //password 超级管理员领锁时需验证该密码 20 + int passwordLength = utf8.encode(password!).length; + data.addAll(utf8.encode(password!)); + data = getFixedLengthList(data, 20 - passwordLength); + + if(needAuthor == 0){ + // 当token失效或者第一次发送的时候token为0 + //Token 4 + data.addAll([0, 0, 0, 0]); + + //AuthCodeLen 1 + data.add(0); + } else { + // token 长度4 首次请求 Token 填 0,如果锁需要鉴权 操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 + data.addAll(userPperationToken!); + + List authCodeData = []; + + //KeyID + authCodeData.addAll(utf8.encode(keyID!)); + + //authUserID + authCodeData.addAll(utf8.encode(authUserID!)); + + //token 4 + authCodeData.addAll(userPperationToken!); + + // String pubKey = ""; + // Storage.getData("bluePublicKey").then((res) => { + // pubKey = res + // }); + // var pubKey = "ovOvAHuL5+dBCw7L3Qt7IQ=="; + // print("pubKey:$pubKey"); + // List pubKeyData = base64.decode(pubKey.toString()); + // print("pubKeyData:$pubKeyData"); + authCodeData.addAll(publicKeyData!); + + // 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode + var authCode = crypto.md5.convert(authCodeData); + // print("authCodeData:$authCodeData \nauthCode:$authCode \nauthCodeBytes:${authCode.bytes}"); + + data.add(authCode.bytes.length); + data.addAll(authCode.bytes); + } + + if ((data.length % 16) != 0) { + int add = (16 - data.length % 16); + for (int i = 0; i < add; i++) { + data.add(0); + } + } + print("SM4Data:$data"); + // 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864 + String key = SM4.createHexKey(key: 'TMH_c3570480da8d'); + ebcData = SM4.encrypt(data, key: key, mode: SM4CryptoMode.ECB); + ebcData.removeRange(ebcData.length - 16, ebcData.length); + // ebcData = utf8.encode(getSM4Str(data, "TMH_c3570480da8d")); + print("ebcData:$ebcData"); + return data; } } diff --git a/star_lock/lib/blue/io_protocol/io_getPrivateKey.dart b/star_lock/lib/blue/io_protocol/io_getPrivateKey.dart index 7e6d35b6..e627b56b 100644 --- a/star_lock/lib/blue/io_protocol/io_getPrivateKey.dart +++ b/star_lock/lib/blue/io_protocol/io_getPrivateKey.dart @@ -2,14 +2,12 @@ import 'dart:convert'; import 'package:star_lock/blue/sm4Encipher/sm4.dart'; -import '../../tools/storage.dart'; import '../io_tool/io_tool.dart'; import 'io_reply.dart'; import 'io_sender.dart'; import 'io_type.dart'; -import 'package:crypto/crypto.dart' as a; -import 'package:convert/convert.dart'; +import 'package:crypto/crypto.dart' as crypto; class GetPrivateKeyCommand extends SenderProtocol { String? lockID; @@ -99,7 +97,7 @@ class GetPrivateKeyCommand extends SenderProtocol { authCodeData.addAll(publicKeyData!); // 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode - var authCode = a.md5.convert(authCodeData); + var authCode = crypto.md5.convert(authCodeData); // print("authCodeData:$authCodeData \nauthCode:$authCode \nauthCodeBytes:${authCode.bytes}"); data.add(authCode.bytes.length); @@ -126,22 +124,30 @@ class GetPrivateKeyCommand extends SenderProtocol { class GetPrivateKeyReply extends Reply { GetPrivateKeyReply.parseData(CommandType commandType, List dataDetail) : super.parseData(commandType, dataDetail) { - print('获取私钥'); - switch(dataDetail[0]){ + var getData = dataDetail.sublist(2); + // print("getData:$getData"); + switch(getData[0]){ case 0x00: //成功 - + print('获取私钥成功'); + getData.removeAt(0); + List commKey = getData.sublist(0, 16); + List signKey = getData.sublist(16); + print("commKey:$commKey signKey:$signKey"); break; case 0x07: - //无权限 + //无权限 + print('获取私钥无权限'); break; case 0x0f: - //用户已存在 + //用户已存在 + print('获取私钥:用户已存在'); break; default: - //失败 + //失败 + print('获取私钥失败'); break; } diff --git a/star_lock/lib/blue/io_protocol/io_getPublicKey.dart b/star_lock/lib/blue/io_protocol/io_getPublicKey.dart index 1a248a8c..0831a925 100644 --- a/star_lock/lib/blue/io_protocol/io_getPublicKey.dart +++ b/star_lock/lib/blue/io_protocol/io_getPublicKey.dart @@ -26,15 +26,15 @@ class GetPublicKeyCommand extends SenderProtocol { int type2 = type%256; data.add(type1); data.add(type2); - print("type:$type"); - print("type1:$type1"); - print("type2:$type2"); + // print("type:$type"); + // print("type1:$type1"); + // print("type2:$type2"); print("lockID:${lockID!} lockID.utf8.encode${utf8.encode(lockID!)}"); int length = utf8.encode(lockID!).length; data.addAll(utf8.encode(lockID!)); data = getFixedLengthList(data, 40 - length); - print("dataaaaaa:$data"); + // print("dataaaaaa:$data"); return data; } } @@ -50,7 +50,7 @@ class GetPublicKeyReply extends Reply { String stringEncoded = base64.encode(tokenData); print('获取公钥成功 publickey:$stringEncoded'); // 储存公钥 - Storage.setData("bluePublicKey", stringEncoded); + // Storage.setData("bluePublicKey", stringEncoded); IoSenderManage.getPrivateKey("TMH_c3570480da8d", "1", "1", 1, tokenData, 1); break; case 0x07: diff --git a/star_lock/lib/blue/io_tool/io_tool.dart b/star_lock/lib/blue/io_tool/io_tool.dart index 3d633952..0d91c114 100644 --- a/star_lock/lib/blue/io_tool/io_tool.dart +++ b/star_lock/lib/blue/io_tool/io_tool.dart @@ -4,28 +4,44 @@ import 'dart:typed_data'; import 'package:crypto/crypto.dart'; import 'package:flutter/services.dart'; import 'package:encrypt/encrypt.dart' as ddd; -// import 'package:sm_crypto/sm_crypto.dart'; -// String getSM4Str(Listdata, String key) { -// String dataStr = radixString(data); -// String iv = SM4.createHexKey(key: key); +List changeIntListToStringList(List list){ + List strList = []; + for(int i = 0; i changeStringListToIntList(List list){ + List intList = []; + for(int i = 0; i= 48 && hexDigit <= 57) { + val += (hexDigit - 48) * (1 << (4 * (len - 1 - i))); + } else if (hexDigit >= 65 && hexDigit <= 70) { + // A..F + val += (hexDigit - 55) * (1 << (4 * (len - 1 - i))); + } else if (hexDigit >= 97 && hexDigit <= 102) { + // a..f + val += (hexDigit - 87) * (1 << (4 * (len - 1 - i))); + } else { + throw new FormatException("Invalid hexadecimal value"); + } + } + return val; +} String md5Crypto(List data) { final dig = md5.convert(data); diff --git a/star_lock/lib/blue/reciver_data.dart b/star_lock/lib/blue/reciver_data.dart index 7187a488..d22fc40e 100644 --- a/star_lock/lib/blue/reciver_data.dart +++ b/star_lock/lib/blue/reciver_data.dart @@ -22,7 +22,7 @@ class CommandReciverManager { if(data_size < 13){ return; } - print("appDataReceiveData:$data"); + // print("appDataReceiveData:$data"); if((data[0] == 0xEF)&&(data[1] == 0x01)&&(data[2] == 0xEE)&&(data[3] == 0x02)&&(data[4] == 0x11)){ var tmpType = (data[7] & 0x0f);// 包标识 print("temType:$tmpType"); @@ -36,19 +36,24 @@ class CommandReciverManager { // for (var i = 0; i < oriLen ; i++) { // oriDataList.add(data[12 + i]); // } - oriDataList = data.sublist(12, 12 + oriLen); + oriDataList = data.sublist(12, 12 + dataLen); print("不加密 oriDataList:$oriDataList"); break; case 1: //AES128 break; case 2: - //SM4(事先约定密钥) + // SM4(事先约定密钥) + // 获取的加密数组 + var getDataList = data.sublist(12, 12 + dataLen); String key = SM4.createHexKey(key: 'TMH_c3570480da8d'); - oriDataList = SM4.decrypt(data, key: key, mode: SM4CryptoMode.ECB); + // 解密 + oriDataList = SM4.decrypt(getDataList, key: key, mode: SM4CryptoMode.ECB); + oriDataList = oriDataList.sublist(0, oriLen); print("SM4 oriDataList:$oriDataList"); break; - case 3: //SM4(设备指定密钥) + case 3: + //SM4(设备指定密钥) // for (var i = 0; i < dataLen ; i++) { // dataView[i] = uint8Recv[12 + i]; // } diff --git a/star_lock/lib/blue/sm4Encipher/sm4.dart b/star_lock/lib/blue/sm4Encipher/sm4.dart index 8cdc9f76..810c8217 100644 --- a/star_lock/lib/blue/sm4Encipher/sm4.dart +++ b/star_lock/lib/blue/sm4Encipher/sm4.dart @@ -411,9 +411,11 @@ class SM4 { } return paddedList; } else { - final lastByte = input.last; - final cutLen = input.length - lastByte; - return input.sublist(0, cutLen); + // final lastByte = input.last; + // final cutLen = input.length - lastByte; + // print("object input.length:${input.length} lastByte:$lastByte input:$input cutLen:$cutLen"); + // return input.sublist(0, cutLen); + return input; } } diff --git a/star_lock/lib/mine/mine/starLockMine_state.dart b/star_lock/lib/mine/mine/starLockMine_state.dart index c29faa5e..8f0d4d3a 100644 --- a/star_lock/lib/mine/mine/starLockMine_state.dart +++ b/star_lock/lib/mine/mine/starLockMine_state.dart @@ -14,13 +14,13 @@ class StarLockMineState { ///本地存储 登录信息 void saveLoginData(LoginEntity data) async { print("saveLoginData:${data.data!.mobile}"); - await Storage.setData('userLoginData',jsonEncode(data)); + await Storage.setString('userLoginData',jsonEncode(data)); loginData.value=data; } ///初始化本地数据 void initLoginData() async { - final data = await Storage.getData('userLoginData'); + final data = await Storage.getString('userLoginData'); print("getLoginData:$data"); if(data != null && data.isNotEmpty){ loginData.value = LoginEntity.fromJson(jsonDecode(data)); @@ -29,7 +29,7 @@ class StarLockMineState { ///退出登录 void logOut() async { - await Storage.setData('userLoginData',''); + await Storage.setString('userLoginData',''); loginData.value = LoginEntity(); } diff --git a/star_lock/lib/network/request_interceptor.dart b/star_lock/lib/network/request_interceptor.dart index 65e11a4f..69f411ff 100644 --- a/star_lock/lib/network/request_interceptor.dart +++ b/star_lock/lib/network/request_interceptor.dart @@ -17,7 +17,7 @@ FutureOr requestInterceptor(Request request) async { // request.headers['token'] = StoreService.to.userToken!; // print("11111${StoreService.to.userToken}"); String? xToken = ''; - final data = await Storage.getData('userLoginData'); + final data = await Storage.getString('userLoginData'); if(data != null && data.isNotEmpty){ xToken = LoginEntity.fromJson(jsonDecode(data)).data!.accessToken; } diff --git a/star_lock/lib/tools/storage.dart b/star_lock/lib/tools/storage.dart index 1c91c7d4..e0c5b5e0 100644 --- a/star_lock/lib/tools/storage.dart +++ b/star_lock/lib/tools/storage.dart @@ -4,33 +4,102 @@ import 'package:shared_preferences/shared_preferences.dart'; class Storage{ - ///存数据 - static Future setData(key, value) async { + + // ///存数据 + // static Future setData(key, value) async { + // SharedPreferences sp = await SharedPreferences.getInstance(); + // if (value is int) { + // await sp.setInt(key, value); + // } else if (value is bool) { + // await sp.setBool(key, value); + // } else if (value is double) { + // await sp.setDouble(key, value); + // } else if (value is String) { + // await sp.setString(key, value); + // } else if (value is List) { + // await sp.setStringList(key, value); + // } + // } + // + // ///取数据 + // /// + // static Future getData(key) async { + // SharedPreferences sp = await SharedPreferences.getInstance(); + // switch(T){ + // case int: return (sp.getInt(key) ?? 0) as T; + // case bool: return (sp.getBool(key) ?? false) as T; + // case double: return (sp.getDouble(key) ?? 0.0) as T; + // case String: return (sp.getString(key) ?? '') as T; + // case List: return (sp.getStringList(key) ?? []) as T; + // default: return null; + // } + // } + + // int + static Future setInt(key,value) async{ SharedPreferences sp = await SharedPreferences.getInstance(); - if (value is int) { - await sp.setInt(key, value); - } else if (value is bool) { - await sp.setBool(key, value); - } else if (value is double) { - await sp.setDouble(key, value); - } else if (value is String) { - await sp.setString(key, value); - } else if (value is List) { - await sp.setStringList(key, value); - } + sp.setInt(key, value); } - ///取数据 - /// - static Future getData(key) async { + static Future getInt(key) async{ SharedPreferences sp = await SharedPreferences.getInstance(); - switch(T){ - case int: return (sp.getInt(key) ?? 0) as T; - case bool: return (sp.getBool(key) ?? false) as T; - case double: return (sp.getDouble(key) ?? 0.0) as T; - case String: return (sp.getString(key) ?? '') as T; - case List: return (sp.getStringList(key) ?? []) as T; - default: return null; - } + return sp.getInt(key); } + + // bool + static Future setBool(key,value) async{ + SharedPreferences sp = await SharedPreferences.getInstance(); + sp.setBool(key, value); + } + + static Future getBool(key) async{ + SharedPreferences sp = await SharedPreferences.getInstance(); + return sp.getBool(key); + } + + // double + static Future setDouble(key,value) async{ + SharedPreferences sp = await SharedPreferences.getInstance(); + sp.setDouble(key, value); + } + + static Future getDouble(key) async{ + SharedPreferences sp = await SharedPreferences.getInstance(); + return sp.getDouble(key); + } + + // string + static Future setString(key,value) async{ + SharedPreferences sp = await SharedPreferences.getInstance(); + sp.setString(key, value); + } + + static Future getString(key) async{ + SharedPreferences sp = await SharedPreferences.getInstance(); + return sp.getString(key); + } + + // 字符串数组 + static Future setStringList(key,value) async{ + SharedPreferences sp = await SharedPreferences.getInstance(); + sp.setStringList(key, value); + } + + static Future?> getStringList(key) async{ + SharedPreferences sp = await SharedPreferences.getInstance(); + return sp.getStringList(key); + } + + // 移除数据 + static Future removeData(key) async{ + SharedPreferences sp = await SharedPreferences.getInstance(); + sp.remove(key); + } + + // 移除所有的键值对 + static Future clearAll() async{ + SharedPreferences sp = await SharedPreferences.getInstance(); + sp.clear(); + } + } \ No newline at end of file From d91f59db481ae0faa3c16c08624a813cb7750d32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AD=8F=E5=B0=91=E9=98=B3?= <786612630@qq.com> Date: Mon, 14 Aug 2023 14:20:35 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E8=B0=83=E8=AF=95=E5=85=AC=E9=92=A5?= =?UTF-8?q?=E6=9C=AC=E5=9C=B0=E5=82=A8=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blue/io_protocol/io_getPrivateKey.dart | 20 +++++++++++-------- .../lib/blue/io_protocol/io_getPublicKey.dart | 6 +++++- star_lock/lib/tools/storage.dart | 13 ++++++++++++ 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/star_lock/lib/blue/io_protocol/io_getPrivateKey.dart b/star_lock/lib/blue/io_protocol/io_getPrivateKey.dart index e627b56b..529da4ed 100644 --- a/star_lock/lib/blue/io_protocol/io_getPrivateKey.dart +++ b/star_lock/lib/blue/io_protocol/io_getPrivateKey.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:star_lock/blue/sm4Encipher/sm4.dart'; +import '../../tools/storage.dart'; import '../io_tool/io_tool.dart'; import 'io_reply.dart'; import 'io_sender.dart'; @@ -86,14 +87,17 @@ class GetPrivateKeyCommand extends SenderProtocol { authCodeData.add((d1 & 0xff00) >> 8); authCodeData.add((d1 & 0xff)); - // String pubKey = ""; - // Storage.getData("bluePublicKey").then((res) => { - // pubKey = res - // }); - // var pubKey = "ovOvAHuL5+dBCw7L3Qt7IQ=="; - // print("pubKey:$pubKey"); - // List pubKeyData = base64.decode(pubKey.toString()); - // print("pubKeyData:$pubKeyData"); + List getIntList; + Storage.getStringList("bluePublicKey").then((res) { + print("getStrList:$res"); + getIntList = changeStringListToIntList(res!); + print("getIntList:$getIntList"); + }); + + // List getStrList = Storage.getLocalStorage("bluePublicKey") as List; + // List getIntList = changeStringListToIntList(getStrList); + + // print("getIntList:$getIntList"); authCodeData.addAll(publicKeyData!); // 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode diff --git a/star_lock/lib/blue/io_protocol/io_getPublicKey.dart b/star_lock/lib/blue/io_protocol/io_getPublicKey.dart index 0831a925..01df7afd 100644 --- a/star_lock/lib/blue/io_protocol/io_getPublicKey.dart +++ b/star_lock/lib/blue/io_protocol/io_getPublicKey.dart @@ -50,7 +50,11 @@ class GetPublicKeyReply extends Reply { String stringEncoded = base64.encode(tokenData); print('获取公钥成功 publickey:$stringEncoded'); // 储存公钥 - // Storage.setData("bluePublicKey", stringEncoded); + var saveStrList = changeIntListToStringList(tokenData); + // Storage.setStringList("bluePublicKey", saveStrList); + Storage.setStringList("bluePublicKey", saveStrList); + // List getStrList = Storage.getLocalStorage("bluePublicKey") as List; + // print('获取储存的公钥 getStrList:$getStrList'); IoSenderManage.getPrivateKey("TMH_c3570480da8d", "1", "1", 1, tokenData, 1); break; case 0x07: diff --git a/star_lock/lib/tools/storage.dart b/star_lock/lib/tools/storage.dart index e0c5b5e0..3cd95157 100644 --- a/star_lock/lib/tools/storage.dart +++ b/star_lock/lib/tools/storage.dart @@ -5,6 +5,19 @@ import 'package:shared_preferences/shared_preferences.dart'; class Storage{ + // Storage._internal(); + // + // factory Storage() => _instance; + // + // static late final Storage _instance = Storage._internal(); + // + // static late SharedPreferences _preferences; + // + // static Future getInstance() async { + // _preferences = await SharedPreferences.getInstance(); + // return _instance; + // } + // ///存数据 // static Future setData(key, value) async { // SharedPreferences sp = await SharedPreferences.getInstance(); From 796cd3a0f68248eb1e05be4cf5e238ba72cd85b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AD=8F=E5=B0=91=E9=98=B3?= <786612630@qq.com> Date: Tue, 15 Aug 2023 18:54:44 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=93=9D=E7=89=99=E5=8D=8F=E8=AE=AE=E8=B0=83?= =?UTF-8?q?=E8=AF=95=EF=BC=8C=E6=B7=BB=E5=8A=A0=E5=85=B6=E4=BB=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- star_lock/lib/blue/blue_manage.dart | 10 +- .../lib/blue/io_protocol/io_addUser.dart | 45 ++--- .../blue/io_protocol/io_getPrivateKey.dart | 54 ++---- .../lib/blue/io_protocol/io_getPublicKey.dart | 31 +--- star_lock/lib/blue/io_protocol/io_reply.dart | 15 +- star_lock/lib/blue/io_protocol/io_sender.dart | 14 +- star_lock/lib/blue/io_protocol/io_type.dart | 18 ++ star_lock/lib/blue/io_tool/io_manager.dart | 19 +- star_lock/lib/blue/io_tool/io_tool.dart | 2 +- star_lock/lib/blue/reciver_data.dart | 37 ++-- star_lock/lib/blue/sender_data.dart | 6 +- star_lock/lib/blue/sender_manage.dart | 80 +++++---- star_lock/lib/blue/sm4Encipher/sm4.dart | 8 +- .../addLock/nearbyLock/nearbyLock_logic.dart | 170 ++++++++++++++++-- .../addLock/nearbyLock/nearbyLock_page.dart | 2 +- .../addLock/nearbyLock/nearbyLock_state.dart | 2 +- 16 files changed, 306 insertions(+), 207 deletions(-) diff --git a/star_lock/lib/blue/blue_manage.dart b/star_lock/lib/blue/blue_manage.dart index 52ae43c3..4617a007 100644 --- a/star_lock/lib/blue/blue_manage.dart +++ b/star_lock/lib/blue/blue_manage.dart @@ -4,6 +4,7 @@ import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'package:star_lock/blue/sender_manage.dart'; import '../app_settings/app_settings.dart'; +import 'io_tool/io_manager.dart'; import 'io_tool/io_tool.dart'; import 'io_tool/manager_event_bus.dart'; import 'reciver_data.dart'; @@ -52,7 +53,6 @@ class BlueManage{ } else { _scanDevices.add(device); } - // EventBusManager().eventBusFir(_scanDevices); scanResultCallBack(_scanDevices); } // _pushState(); @@ -62,13 +62,15 @@ class BlueManage{ } /// 连接监听状态 - Future connect(String deviceMAC) async { + Future connect(String deviceMAC, String deviceName) async { print("connect:$deviceMAC"); _flutterReactiveBle!.connectToDevice(id: deviceMAC).listen((connectionStateUpdate) { print('ConnectionState for device $deviceMAC : ${connectionStateUpdate.connectionState}'); // EventBusManager().eventBusFir(connectionStateUpdate); if(connectionStateUpdate.connectionState == DeviceConnectionState.connected){ // getPublicKey(update.deviceId); + // 先配置lockId + IoManager().configCurrentDeviceLockId(deviceName); // 如果状态是连接的开始发现服务 discoverServices(deviceMAC); } @@ -137,7 +139,7 @@ class BlueManage{ _flutterReactiveBle!.subscribeToCharacteristic(characteristic).listen((data) { // code to handle incoming data print("subscribeToCharacteristic: deviceId = ${characteristic.deviceId} characteristicId =${characteristic.characteristicId}---上报来的数据data = $data"); - CommandReciverManager.appDataReceive(data, ""); + CommandReciverManager.appDataReceive(data); }, onError: (dynamic error) { print("subscribeToCharacteristic error:$error"); }); @@ -145,7 +147,7 @@ class BlueManage{ // 写入 Future writeCharacteristicWithResponse(QualifiedCharacteristic characteristic, List value) async { - print('Write with characteristicId:${characteristic.characteristicId} serviceId:${characteristic.serviceId} deviceId:${characteristic.deviceId} value : $value \nhexStr:${radixString(value)}'); + print('Write with characteristicId:${characteristic.characteristicId} serviceId:${characteristic.serviceId} deviceId:${characteristic.deviceId} value : $value \nhexStr:${radixHex16String(value)}'); try { List valueList = value; diff --git a/star_lock/lib/blue/io_protocol/io_addUser.dart b/star_lock/lib/blue/io_protocol/io_addUser.dart index 88b757f2..f23dc160 100644 --- a/star_lock/lib/blue/io_protocol/io_addUser.dart +++ b/star_lock/lib/blue/io_protocol/io_addUser.dart @@ -1,6 +1,8 @@ import 'dart:convert'; +import '../../tools/storage.dart'; +import '../io_tool/io_manager.dart'; import '../io_tool/io_tool.dart'; import '../sm4Encipher/sm4.dart'; import 'io_reply.dart'; @@ -22,8 +24,9 @@ class AddUserCommand extends SenderProtocol { int? role; String? password; int? needAuthor; - List? userPperationToken; - List? publicKeyData; + List? publicKey; + List? privateKey; + List? token; AddUserCommand({ this.lockID, this.authUserID, @@ -36,8 +39,9 @@ class AddUserCommand extends SenderProtocol { this.role, this.password, this.needAuthor, - this.userPperationToken, - this.publicKeyData + this.publicKey, + this.privateKey, + this.token }) : super(CommandType.addUser); @override @@ -111,13 +115,13 @@ class AddUserCommand extends SenderProtocol { if(needAuthor == 0){ // 当token失效或者第一次发送的时候token为0 //Token 4 - data.addAll([0, 0, 0, 0]); + data.addAll(token!); //AuthCodeLen 1 data.add(0); } else { // token 长度4 首次请求 Token 填 0,如果锁需要鉴权 操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 - data.addAll(userPperationToken!); + data.addAll(token!); List authCodeData = []; @@ -127,22 +131,13 @@ class AddUserCommand extends SenderProtocol { //authUserID authCodeData.addAll(utf8.encode(authUserID!)); - //token 4 - authCodeData.addAll(userPperationToken!); + //token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 + data.addAll([0, 0, 0, 0]); - // String pubKey = ""; - // Storage.getData("bluePublicKey").then((res) => { - // pubKey = res - // }); - // var pubKey = "ovOvAHuL5+dBCw7L3Qt7IQ=="; - // print("pubKey:$pubKey"); - // List pubKeyData = base64.decode(pubKey.toString()); - // print("pubKeyData:$pubKeyData"); - authCodeData.addAll(publicKeyData!); + authCodeData.addAll(publicKey!); // 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode var authCode = crypto.md5.convert(authCodeData); - // print("authCodeData:$authCodeData \nauthCode:$authCode \nauthCodeBytes:${authCode.bytes}"); data.add(authCode.bytes.length); data.addAll(authCode.bytes); @@ -154,22 +149,16 @@ class AddUserCommand extends SenderProtocol { data.add(0); } } - print("SM4Data:$data"); + print("addUserSM4Data:$data"); // 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864 - String key = SM4.createHexKey(key: 'TMH_c3570480da8d'); - ebcData = SM4.encrypt(data, key: key, mode: SM4CryptoMode.ECB); - ebcData.removeRange(ebcData.length - 16, ebcData.length); - // ebcData = utf8.encode(getSM4Str(data, "TMH_c3570480da8d")); - print("ebcData:$ebcData"); - - return data; + ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB); + return ebcData; } } class AddUserReply extends Reply { AddUserReply.parseData(CommandType commandType, List dataDetail) : super.parseData(commandType, dataDetail) { - int index = 0; - + data = dataDetail; } } \ No newline at end of file diff --git a/star_lock/lib/blue/io_protocol/io_getPrivateKey.dart b/star_lock/lib/blue/io_protocol/io_getPrivateKey.dart index 529da4ed..e9c47337 100644 --- a/star_lock/lib/blue/io_protocol/io_getPrivateKey.dart +++ b/star_lock/lib/blue/io_protocol/io_getPrivateKey.dart @@ -3,13 +3,17 @@ import 'dart:convert'; import 'package:star_lock/blue/sm4Encipher/sm4.dart'; import '../../tools/storage.dart'; +import '../io_tool/io_manager.dart'; import '../io_tool/io_tool.dart'; +import '../sender_manage.dart'; import 'io_reply.dart'; import 'io_sender.dart'; import 'io_type.dart'; import 'package:crypto/crypto.dart' as crypto; +ListpublicKeyDataList = []; + class GetPrivateKeyCommand extends SenderProtocol { String? lockID; String? keyID; // 钥匙ID @@ -28,6 +32,7 @@ class GetPrivateKeyCommand extends SenderProtocol { @override List messageDetail() { + publicKeyDataList = publicKeyData!; List data = []; List ebcData = []; // print("lockID:${lockID!} lockID.utf8.encode${utf8.encode(lockID!)}"); @@ -87,22 +92,10 @@ class GetPrivateKeyCommand extends SenderProtocol { authCodeData.add((d1 & 0xff00) >> 8); authCodeData.add((d1 & 0xff)); - List getIntList; - Storage.getStringList("bluePublicKey").then((res) { - print("getStrList:$res"); - getIntList = changeStringListToIntList(res!); - print("getIntList:$getIntList"); - }); - - // List getStrList = Storage.getLocalStorage("bluePublicKey") as List; - // List getIntList = changeStringListToIntList(getStrList); - - // print("getIntList:$getIntList"); authCodeData.addAll(publicKeyData!); // 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode var authCode = crypto.md5.convert(authCodeData); - // print("authCodeData:$authCodeData \nauthCode:$authCode \nauthCodeBytes:${authCode.bytes}"); data.add(authCode.bytes.length); data.addAll(authCode.bytes); @@ -114,13 +107,10 @@ class GetPrivateKeyCommand extends SenderProtocol { data.add(0); } } - print("SM4Data:$data"); + // print("SM4Data:$data"); // 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864 - String key = SM4.createHexKey(key: 'TMH_c3570480da8d'); - ebcData = SM4.encrypt(data, key: key, mode: SM4CryptoMode.ECB); - ebcData.removeRange(ebcData.length - 16, ebcData.length); - // ebcData = utf8.encode(getSM4Str(data, "TMH_c3570480da8d")); - print("ebcData:$ebcData"); + ebcData = SM4.encrypt(data, key: utf8.encode(IoManager().getCurrentDeviceLockId), mode: SM4CryptoMode.ECB); + return ebcData; } } @@ -128,32 +118,8 @@ class GetPrivateKeyCommand extends SenderProtocol { class GetPrivateKeyReply extends Reply { GetPrivateKeyReply.parseData(CommandType commandType, List dataDetail) : super.parseData(commandType, dataDetail) { - var getData = dataDetail.sublist(2); + data = dataDetail.sublist(2); + status = data[0]; // print("getData:$getData"); - switch(getData[0]){ - case 0x00: - //成功 - print('获取私钥成功'); - getData.removeAt(0); - List commKey = getData.sublist(0, 16); - List signKey = getData.sublist(16); - print("commKey:$commKey signKey:$signKey"); - break; - case 0x07: - //无权限 - print('获取私钥无权限'); - - break; - case 0x0f: - //用户已存在 - print('获取私钥:用户已存在'); - - break; - default: - //失败 - print('获取私钥失败'); - - break; - } } } diff --git a/star_lock/lib/blue/io_protocol/io_getPublicKey.dart b/star_lock/lib/blue/io_protocol/io_getPublicKey.dart index 01df7afd..2ebbdf3b 100644 --- a/star_lock/lib/blue/io_protocol/io_getPublicKey.dart +++ b/star_lock/lib/blue/io_protocol/io_getPublicKey.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'dart:typed_data'; import '../../tools/storage.dart'; +import '../io_tool/io_manager.dart'; import '../io_tool/io_tool.dart'; import '../sender_manage.dart'; import 'io_reply.dart'; @@ -42,33 +43,7 @@ class GetPublicKeyCommand extends SenderProtocol { class GetPublicKeyReply extends Reply { GetPublicKeyReply.parseData(CommandType commandType, List dataDetail) : super.parseData(commandType, dataDetail) { - var tokenData = dataDetail.sublist(3); - print('获取公钥:dataDetail:$dataDetail tokenData:$tokenData'); - switch(dataDetail[2]){ - case 0x00: - //成功 - String stringEncoded = base64.encode(tokenData); - print('获取公钥成功 publickey:$stringEncoded'); - // 储存公钥 - var saveStrList = changeIntListToStringList(tokenData); - // Storage.setStringList("bluePublicKey", saveStrList); - Storage.setStringList("bluePublicKey", saveStrList); - // List getStrList = Storage.getLocalStorage("bluePublicKey") as List; - // print('获取储存的公钥 getStrList:$getStrList'); - IoSenderManage.getPrivateKey("TMH_c3570480da8d", "1", "1", 1, tokenData, 1); - break; - case 0x07: - //无权限 - - break; - case 0x0f: - //用户已存在 - - break; - default: - //失败 - - break; - } + status = dataDetail[2]; + data = dataDetail; } } \ No newline at end of file diff --git a/star_lock/lib/blue/io_protocol/io_reply.dart b/star_lock/lib/blue/io_protocol/io_reply.dart index 540c13fa..c4ba500c 100644 --- a/star_lock/lib/blue/io_protocol/io_reply.dart +++ b/star_lock/lib/blue/io_protocol/io_reply.dart @@ -1,22 +1,13 @@ import 'io_type.dart'; abstract class Reply{ - //value字节长度 - int? packetHeader = 4; // 包头4个字节 - int? packetType = 1; // 包类型1个字节 - int? packetNumber = 1; // 包序号 - int? packetIdentifier = 1; // 包标识 - int? packetLength = 4; // 包标识 + CommandType? commandType; - int? packetMcrc = 2; // 校验位 //command key flag - int commandKey = 0; - + int status = 0; + List data = []; Reply.parseData(this.commandType, List dataDetail); - // Reply({this.result}); - // bool get isSuccessfully => packetHeader == EF01EE02; - } \ No newline at end of file diff --git a/star_lock/lib/blue/io_protocol/io_sender.dart b/star_lock/lib/blue/io_protocol/io_sender.dart index 60cd5333..72db1350 100644 --- a/star_lock/lib/blue/io_protocol/io_sender.dart +++ b/star_lock/lib/blue/io_protocol/io_sender.dart @@ -48,17 +48,9 @@ abstract class SenderProtocol extends IOData { // print("_commandIndex:$_commandIndex commandIndexChang1$commandIndexChang1 commandIndexChang2:$commandIndexChang2"); // 包标识 - // 指令类型 - int type = commandType!.typeValue; - if(type == 0x3090){ - // 不加密 - identifier = 0x20; - }else if(type == 0x3091){ - // 不加密 - identifier = 0x22; - } - commandList.add(identifier); - // print("identifier:$identifier"); + // 指令类型 高 4 位表示包版本,低 4 位用来指示后面数据的加密类型,长度为 1 字节,加密类型取值说明,0:明文,1:AES128,2:SM4(事先约定密钥),3:SM4(设备指定密钥) + commandList.add(commandType!.identifierValue); + print("commandType!.identifierValue:${commandType!.identifierValue}"); // 数据长度 int dataLen = dataSourceLength(); diff --git a/star_lock/lib/blue/io_protocol/io_type.dart b/star_lock/lib/blue/io_protocol/io_type.dart index 2a516eb7..fbad2570 100644 --- a/star_lock/lib/blue/io_protocol/io_type.dart +++ b/star_lock/lib/blue/io_protocol/io_type.dart @@ -1,4 +1,6 @@ //TODO:发送指令类型 +import 'package:get/get.dart'; + enum CommandType { addUser, //增加用户 = 0x3001 deletUser , //删除用户 = 0x3002 @@ -164,6 +166,22 @@ extension ExtensionCommandType on CommandType { return type; } + int get identifierValue { + int type = 0x23; + switch(this){ + case CommandType.getLockPublicKey: + type = 0x20; + break; + case CommandType.getLockPrivateKey: + type = 0x22; + break; + default: + type = 0x23; + break; + } + return type; + } + String get typeName { String t = ''; switch(typeValue){ diff --git a/star_lock/lib/blue/io_tool/io_manager.dart b/star_lock/lib/blue/io_tool/io_manager.dart index 8d8c8283..bbd5afce 100644 --- a/star_lock/lib/blue/io_tool/io_manager.dart +++ b/star_lock/lib/blue/io_tool/io_manager.dart @@ -3,6 +3,11 @@ enum DataTransmissionMode { ble, } +const saveBluePublicKey = "BluePublicKey"; +const saveBluePrivateKey = "BluePrivateKey"; +const saveBlueSignKey = "BlueSignKey"; +const saveBlueToken = "BlueToken"; + class IoManager { static IoManager? _ioManager; @@ -21,18 +26,20 @@ class IoManager { ///蓝牙传输协议 void bleTransmission() => _dataTransmissionMode = DataTransmissionMode.ble; - int _commandIndex = 1; //割草机协议帧序号 + ///割草机协议帧序号 + int _commandIndex = 1; configCommandIdx(int idx) => _commandIndex = idx; Future increaseCommandIndex() async { _commandIndex < 255 ? _commandIndex++ : _commandIndex = 0; } - - void resetCommandIndex(){ - _commandIndex = 0; - } - + void resetCommandIndex() => _commandIndex = 0; int get commandIndex => _commandIndex; + /// 当前设备连接的lockId + String _currentDeviceLockId = ""; + configCurrentDeviceLockId(String lockId) => _currentDeviceLockId = lockId; + String get getCurrentDeviceLockId => _currentDeviceLockId; + void resetAllFlags() { resetCommandIndex(); } diff --git a/star_lock/lib/blue/io_tool/io_tool.dart b/star_lock/lib/blue/io_tool/io_tool.dart index 0d91c114..54c7dd3a 100644 --- a/star_lock/lib/blue/io_tool/io_tool.dart +++ b/star_lock/lib/blue/io_tool/io_tool.dart @@ -254,7 +254,7 @@ List> splitList(List list, int len) { //TODO:int->两个字节 List 高字节在前,低字节在后(小端存储) 本工程只有配置 WiFi用到的!!!! List intToByte2ListLow(int value) => [value >> 8, value]; -String radixString(List codeUnits) { +String radixHex16String(List codeUnits) { String result = ''; codeUnits.forEach((value) { result += value.toRadixString(16).padLeft(2, '0'); diff --git a/star_lock/lib/blue/reciver_data.dart b/star_lock/lib/blue/reciver_data.dart index d22fc40e..caad6a37 100644 --- a/star_lock/lib/blue/reciver_data.dart +++ b/star_lock/lib/blue/reciver_data.dart @@ -1,18 +1,22 @@ +import 'dart:convert'; + +import '../tools/storage.dart'; import 'io_protocol/io_addUser.dart'; import 'io_protocol/io_getPrivateKey.dart'; import 'io_protocol/io_getPublicKey.dart'; import 'io_protocol/io_openDoor.dart'; import 'io_protocol/io_reply.dart'; import 'io_protocol/io_type.dart'; +import 'io_tool/io_manager.dart'; import 'io_tool/io_tool.dart'; import 'io_tool/manager_event_bus.dart'; import 'sm4Encipher/sm4.dart'; class CommandReciverManager { - static void appDataReceive(List data, String lockId) async { + static void appDataReceive(List data) async { ///解析数据 if(data.isEmpty){ return; @@ -46,28 +50,26 @@ class CommandReciverManager { // SM4(事先约定密钥) // 获取的加密数组 var getDataList = data.sublist(12, 12 + dataLen); - String key = SM4.createHexKey(key: 'TMH_c3570480da8d'); + // 解密 - oriDataList = SM4.decrypt(getDataList, key: key, mode: SM4CryptoMode.ECB); + // String key = SM4.createHexKey(key: IoManager().getCurrentDeviceLockId); + oriDataList = SM4.decrypt(getDataList, key: utf8.encode(IoManager().getCurrentDeviceLockId), mode: SM4CryptoMode.ECB); oriDataList = oriDataList.sublist(0, oriLen); print("SM4 oriDataList:$oriDataList"); break; case 3: //SM4(设备指定密钥) - // for (var i = 0; i < dataLen ; i++) { - // dataView[i] = uint8Recv[12 + i]; - // } - // console.log("dataView.length = ", dataView.length); - // console.log("currCommStru.pairCommKey = ", currCommStru.pairCommKey); - // var commKey1 = base64js.toByteArray(currCommStru.pairCommKey); - // console.log("commKey1 = ", commKey1); - // var d_cbc = cbc.decrypt_ecb(dataView, commKey1, false, "nobase64"); - // console.log("d_cbc = ", d_cbc); - // console.log("oriLen = ", oriLen); - // for (var i = 0; i < oriLen ; i++) { - // oriDataView[i] = d_cbc[i]; - // } - // console.log("oriDataView = ", oriDataView); + // 获取的加密数组 + var getDataList = data.sublist(12, 12 + dataLen); + + var res = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(res!); + + // 解密 + // String key = SM4.createHexKey(key: radixHex16String(getPrivateKeyList!)); + oriDataList = SM4.decrypt(getDataList, key: getPrivateKeyList, mode: SM4CryptoMode.ECB); + oriDataList = oriDataList.sublist(0, oriLen); + print("SM4 oriDataList:$oriDataList"); break; } @@ -82,6 +84,7 @@ class CommandReciverManager { if(data.isNotEmpty){ var cmd = data[0] * 256 + data[1]; CommandType commandType = ExtensionCommandType.getCommandType(cmd); + await IoManager().increaseCommandIndex(); // data.removeRange(0, 2); print("111111data cmd:$cmd commandType:$commandType data:$data"); var reply; diff --git a/star_lock/lib/blue/sender_data.dart b/star_lock/lib/blue/sender_data.dart index 02385b26..dc94b46b 100644 --- a/star_lock/lib/blue/sender_data.dart +++ b/star_lock/lib/blue/sender_data.dart @@ -24,9 +24,9 @@ class CommandSenderManager { bool canSendControlCommand = false; //TODO:发送常规数据 - void managerSendData ({ + Future managerSendData ({ required SenderProtocol command, - CommandSendCallBack? callBack}) { + CommandSendCallBack? callBack}) async { if (callBack != null) { // if (!BluetoothManager().connected) { print('❌ 蓝牙断开了'); @@ -38,7 +38,7 @@ class CommandSenderManager { return; } - List value = command.packageData(); + List value = await command.packageData(); // print("sendData:${value}"); _sendNormalData(value); } diff --git a/star_lock/lib/blue/sender_manage.dart b/star_lock/lib/blue/sender_manage.dart index 3e9f839a..0b78dbe5 100644 --- a/star_lock/lib/blue/sender_manage.dart +++ b/star_lock/lib/blue/sender_manage.dart @@ -8,50 +8,66 @@ import 'sender_data.dart'; class IoSenderManage { //todo:获取公钥 - static void getPublicKey(String lockId ,{CommandSendCallBack? callBack}) { + static void getPublicKey({String? lockId ,CommandSendCallBack? callBack}) { CommandSenderManager().managerSendData(command: GetPublicKeyCommand( lockID: lockId, ), callBack:callBack); } //todo:获取私钥 - static void getPrivateKey( - String? lockId, - String? keyID, // 钥匙ID - String? authUserID,// 钥匙授权人ID - int? nowTime, - List? publicKeyData, - int? needAuthor, {CommandSendCallBack? callBack}) { + static void getPrivateKey({ + String? lockId, + String? keyID, // 钥匙ID + String? authUserID,// 钥匙授权人ID + int? nowTime, + List? publicKeyData, + int? needAuthor, + CommandSendCallBack? callBack}) { CommandSenderManager().managerSendData(command: GetPrivateKeyCommand( lockID: lockId, - keyID: keyID, - authUserID: authUserID, - nowTime: nowTime, - publicKeyData:publicKeyData, - needAuthor: needAuthor, + keyID: keyID, + authUserID: authUserID, + nowTime: nowTime, + publicKeyData:publicKeyData, + needAuthor: needAuthor, ), callBack:callBack); } //todo:添加用户 - // static void senderAddUser({CommandSendCallBack? callBack}) { - // CommandSenderManager().managerSendData( - // command: AddUserCommand( - // cmdID: 0, - // lockID: "", - // authUserID: "", - // keyID: "", - // userID: "", - // openMode: 0, - // keyType: 0, - // startDate: 0, - // expireDate: 0, - // role: 0, - // password: "", - // token: 0, - // authCodeLen: 0, - // authCode: "", - // ), callBack:callBack); - // } + static void senderAddUser({ + String? lockID, + String? authUserID, + String? keyID, + String? userID, + int? openMode, + int? keyType, + int? startDate, + int? expireDate, + int? role, + String? password, + int? needAuthor, + List? publicKey, + List? privateKey, + List? token, + CommandSendCallBack? callBack}) { + CommandSenderManager().managerSendData( + command: AddUserCommand( + lockID: lockID, + authUserID: authUserID, + keyID: keyID, + userID: userID, + openMode: openMode, + keyType: keyType, + startDate: startDate, + expireDate: expireDate, + role: role, + password: password, + needAuthor: needAuthor, + publicKey: publicKey, + privateKey: privateKey, + token: token + ), callBack:callBack); + } //todo:开锁 // static void senderOpenDoor({CommandSendCallBack? callBack}) { diff --git a/star_lock/lib/blue/sm4Encipher/sm4.dart b/star_lock/lib/blue/sm4Encipher/sm4.dart index 810c8217..3a4941a2 100644 --- a/star_lock/lib/blue/sm4Encipher/sm4.dart +++ b/star_lock/lib/blue/sm4Encipher/sm4.dart @@ -359,8 +359,8 @@ class SM4 { return roundKey; } - static void setKey(String key) { - List keyBytes = SMUtils.hexStringToBytes(key); + static void setKey(List key) { + List keyBytes = key; List intermediateKeys = List.filled(36, 0); for (int i = 0; i < 4; i++) { intermediateKeys[i] = _readUint32BE(keyBytes, i * 4) ^ FK[i]; @@ -520,7 +520,7 @@ class SM4 { } static List encrypt(List data, - {String? key, SM4CryptoMode mode = SM4CryptoMode.ECB, String? iv}) { + {List? key, SM4CryptoMode mode = SM4CryptoMode.ECB, String? iv}) { if (key != null) setKey(key); List input = data; List output = _crypto(input, SM4_ENCRYPT, mode, iv); @@ -536,7 +536,7 @@ class SM4 { // } static decrypt(List data, - {String? key, SM4CryptoMode mode = SM4CryptoMode.ECB, String? iv}) { + {List? key, SM4CryptoMode mode = SM4CryptoMode.ECB, String? iv}) { if (key != null) setKey(key); List input = data; List output = _crypto(input, SM4_DECRYPT, mode, iv); diff --git a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart index a2387f95..33caf487 100644 --- a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart +++ b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart @@ -2,12 +2,20 @@ import 'dart:async'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; +import 'package:get_storage/get_storage.dart'; +import 'package:star_lock/blue/io_protocol/io_getPrivateKey.dart'; +import 'package:star_lock/blue/io_protocol/io_getPublicKey.dart'; import 'package:star_lock/tools/baseGetXController.dart'; import '../../../blue/blue_manage.dart'; +import '../../../blue/io_protocol/io_addUser.dart'; +import '../../../blue/io_protocol/io_reply.dart'; +import '../../../blue/io_tool/io_manager.dart'; import '../../../blue/io_tool/io_model.dart'; +import '../../../blue/io_tool/io_tool.dart'; import '../../../blue/io_tool/manager_event_bus.dart'; import '../../../blue/sender_manage.dart'; +import '../../../tools/storage.dart'; import 'nearbyLock_state.dart'; class NearbyLockLogic extends BaseGetXController{ @@ -15,26 +23,18 @@ class NearbyLockLogic extends BaseGetXController{ final NearbyLockState state = NearbyLockState(); // 点击复合要求的设备之后 连接 - void connect(String lockId){ - BlueManage().connect(lockId); + void connect(String lockId, String deviceName){ + BlueManage().connect(lockId, deviceName); } // 监听蓝牙连接的状态 late StreamSubscription _streamSubscription; void _startListenIO(){ _streamSubscription = EventBusManager().eventBus!.on().listen((event) async { - IoSenderManage.getPublicKey(state.seletLockName.value); + IoSenderManage.getPublicKey(lockId:state.seletLockName.value); }); } - // 状态在线之后发现服务 - // Future scanDiscoverServices(String lockId) async { - // // 获取特征值 处理特征值 - // List list = await BlueManage().discoverServices(lockId); - // // 发送获取公钥 - // IoSenderManage.getPublicKey(state.seletLockName.value); - // } - // 获取公钥 // void getPublicKey(String lockId){ // // print("seletGetPublicKey:${lockId}"); @@ -57,6 +57,146 @@ class NearbyLockLogic extends BaseGetXController{ }); } + late StreamSubscription _replySubscription; + void _initReplySubscription() { + _replySubscription = EventBusManager().eventBus!.on().listen((reply) { + if(reply is GetPublicKeyReply) { + _replyGetPublicKey(reply); + } + + if(reply is GetPrivateKeyReply) { + _replyGetPrivateKeyKey(reply); + } + + if(reply is AddUserReply) { + _replyAddUserKey(reply); + } + }); + } + + void _replyGetPublicKey(Reply reply){ + // 获取公钥 + switch(reply.status){ + case 0x00: + //成功 + // 储存公钥 + var tokenData = reply.data.sublist(3); + var saveStrList = changeIntListToStringList(tokenData); + Storage.setStringList(saveBluePublicKey, saveStrList); + IoSenderManage.getPrivateKey( + lockId:IoManager().getCurrentDeviceLockId, + keyID:"1", + authUserID:"1", + nowTime:1, + publicKeyData:tokenData, + needAuthor:1); + break; + case 0x07: + //无权限 + + break; + case 0x0f: + //用户已存在 + + break; + default: + //失败 + + break; + } + } + + void _replyGetPrivateKeyKey(Reply reply){ + switch(reply.status){ + case 0x00: + //成功 + print('获取私钥成功'); + reply.data.removeAt(0); + + // 私钥 + List privateKey = reply.data.sublist(0, 16); + var savePrivateKeyList = changeIntListToStringList(privateKey); + Storage.setStringList(saveBluePrivateKey, savePrivateKeyList); + + // signKey + List signKey = reply.data.sublist(16); + var savesignKeyList = changeIntListToStringList(signKey); + Storage.setStringList(saveBlueSignKey, savesignKeyList); + + print("privateKey:$privateKey signKey:$signKey"); + IoSenderManage.senderAddUser( + lockID:IoManager().getCurrentDeviceLockId, + authUserID:"100001", + keyID:"1", + userID:"100001", + openMode:1, + keyType:1, + startDate:0x11223344, + expireDate:0x11223344, + role:255, + password:"123456", + needAuthor:1, + publicKey:publicKeyDataList, + privateKey:privateKey, + token: [0,0,0,0] + ); + break; + case 0x07: + //无权限 + print('获取私钥无权限'); + + break; + case 0x0f: + //用户已存在 + print('获取私钥:用户已存在'); + + break; + default: + //失败 + print('获取私钥失败'); + + break; + } + } + + void _replyAddUserKey(Reply reply){ + var lockId = reply.data.sublist(2, 42); + print("lockId:$lockId"); + var token = reply.data.sublist(42, 46); + List strTokenList = changeIntListToStringList(token); + Storage.setStringList(saveBlueToken, strTokenList); + print("token:$token"); + int status = reply.data[46]; + print("status:$status"); + switch(status){ + case 0x00: + //成功 + print("添加用户数据解析成功"); + + break; + case 0x06: + //无权限 + print("需要鉴权"); + + break; + case 0x07: + //无权限 + print("用户无权限"); + + break; + case 0x09: + // 权限校验错误 + print("权限校验错误"); + + break; + default: + //失败 + print("领锁失败"); + + break; + } + } + @override void onReady() { // TODO: implement onReady @@ -65,6 +205,7 @@ class NearbyLockLogic extends BaseGetXController{ _startListenIO(); _initSendStreamSubscription(); + _initReplySubscription(); } @override @@ -75,10 +216,8 @@ class NearbyLockLogic extends BaseGetXController{ // 进来第一步开始扫描 BlueManage().startScan((v){ - bool isHave = state.devices.any((element) => element.id == v[0].id); - if (isHave == false){ - state.devices.addAll(v); - } + state.devices.clear(); + state.devices.addAll(v); }); } @@ -88,6 +227,7 @@ class NearbyLockLogic extends BaseGetXController{ super.onClose(); _streamSubscription.cancel(); _sendStreamSubscription.cancel(); + _replySubscription.cancel(); } } diff --git a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_page.dart b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_page.dart index 3810c9f7..b6d96584 100644 --- a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_page.dart +++ b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_page.dart @@ -61,7 +61,7 @@ class _NearbyLockPageState extends State { // Navigator.pushNamed(context, Routers.lockAddressPage); // logic.getPublicKey(state.devices[index].serviceUuids[0].toString()); state.seletLockName.value = state.devices[index].name; - logic.connect(state.devices[index].id); + logic.connect(state.devices[index].id, state.devices[index].name); }); }, separatorBuilder: (BuildContext context, int index) { diff --git a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_state.dart b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_state.dart index 92afceec..508ac241 100644 --- a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_state.dart +++ b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_state.dart @@ -6,6 +6,6 @@ import 'package:get/get.dart'; class NearbyLockState { - var devices = [].obs; + RxList devices = [].obs; var seletLockName = "".obs; } \ No newline at end of file