diff --git a/lib/blue/reciver_data.dart b/lib/blue/reciver_data.dart index 8f1db2af..2fc7fe54 100755 --- a/lib/blue/reciver_data.dart +++ b/lib/blue/reciver_data.dart @@ -57,7 +57,20 @@ class CommandReciverManager { if (data.isEmpty) { return; } + final int dataSize = data.length; + + // 验证CRC校验 + if (dataSize >= 2) { + final int calculatedCrc = + _calculateCRC16(data.sublist(0, dataSize - 2), dataSize - 2); + final int receivedCrc = (data[dataSize - 2] << 8) | data[dataSize - 1]; + + if (calculatedCrc != receivedCrc) { + AppLog.log('CRC校验失败'); + return; + } + } // 当小于包头加起来13个字节 if (dataSize < 13) { return; @@ -123,6 +136,16 @@ class CommandReciverManager { } } +// CRC16 校验计算 + static int _calculateCRC16(List bytes, int len) { + int value = 0x0000; + for (int i = 0; i < len; i++) { + int tmp = _reverse8(bytes[i]); + value = ((value << 8) ^ _crcTable[(value >> 8) ^ tmp & 0xFF]) & 0xFFFF; + } + return _reverse16(value); + } + static Future parseData(List data) async { if (data.isNotEmpty) { final int cmd = data[0] * 256 + data[1]; @@ -472,4 +495,282 @@ class CommandReciverManager { } return null; } + + // CRC16 查找表 + static const List _crcTable = [ + 0x0000, + 0x1021, + 0x2042, + 0x3063, + 0x4084, + 0x50a5, + 0x60c6, + 0x70e7, + 0x8108, + 0x9129, + 0xa14a, + 0xb16b, + 0xc18c, + 0xd1ad, + 0xe1ce, + 0xf1ef, + 0x1231, + 0x0210, + 0x3273, + 0x2252, + 0x52b5, + 0x4294, + 0x72f7, + 0x62d6, + 0x9339, + 0x8318, + 0xb37b, + 0xa35a, + 0xd3bd, + 0xc39c, + 0xf3ff, + 0xe3de, + 0x2462, + 0x3443, + 0x0420, + 0x1401, + 0x64e6, + 0x74c7, + 0x44a4, + 0x5485, + 0xa56a, + 0xb54b, + 0x8528, + 0x9509, + 0xe5ee, + 0xf5cf, + 0xc5ac, + 0xd58d, + 0x3653, + 0x2672, + 0x1611, + 0x0630, + 0x76d7, + 0x66f6, + 0x5695, + 0x46b4, + 0xb75b, + 0xa77a, + 0x9719, + 0x8738, + 0xf7df, + 0xe7fe, + 0xd79d, + 0xc7bc, + 0x48c4, + 0x58e5, + 0x6886, + 0x78a7, + 0x0840, + 0x1861, + 0x2802, + 0x3823, + 0xc9cc, + 0xd9ed, + 0xe98e, + 0xf9af, + 0x8948, + 0x9969, + 0xa90a, + 0xb92b, + 0x5af5, + 0x4ad4, + 0x7ab7, + 0x6a96, + 0x1a71, + 0x0a50, + 0x3a33, + 0x2a12, + 0xdbfd, + 0xcbdc, + 0xfbbf, + 0xeb9e, + 0x9b79, + 0x8b58, + 0xbb3b, + 0xab1a, + 0x6ca6, + 0x7c87, + 0x4ce4, + 0x5cc5, + 0x2c22, + 0x3c03, + 0x0c60, + 0x1c41, + 0xedae, + 0xfd8f, + 0xcdec, + 0xddcd, + 0xad2a, + 0xbd0b, + 0x8d68, + 0x9d49, + 0x7e97, + 0x6eb6, + 0x5ed5, + 0x4ef4, + 0x3e13, + 0x2e32, + 0x1e51, + 0x0e70, + 0xff9f, + 0xefbe, + 0xdfdd, + 0xcffc, + 0xbf1b, + 0xaf3a, + 0x9f59, + 0x8f78, + 0x9188, + 0x81a9, + 0xb1ca, + 0xa1eb, + 0xd10c, + 0xc12d, + 0xf14e, + 0xe16f, + 0x1080, + 0x00a1, + 0x30c2, + 0x20e3, + 0x5004, + 0x4025, + 0x7046, + 0x6067, + 0x83b9, + 0x9398, + 0xa3fb, + 0xb3da, + 0xc33d, + 0xd31c, + 0xe37f, + 0xf35e, + 0x02b1, + 0x1290, + 0x22f3, + 0x32d2, + 0x4235, + 0x5214, + 0x6277, + 0x7256, + 0xb5ea, + 0xa5cb, + 0x95a8, + 0x8589, + 0xf56e, + 0xe54f, + 0xd52c, + 0xc50d, + 0x34e2, + 0x24c3, + 0x14a0, + 0x0481, + 0x7466, + 0x6447, + 0x5424, + 0x4405, + 0xa7db, + 0xb7fa, + 0x8799, + 0x97b8, + 0xe75f, + 0xf77e, + 0xc71d, + 0xd73c, + 0x26d3, + 0x36f2, + 0x0691, + 0x16b0, + 0x6657, + 0x7676, + 0x4615, + 0x5634, + 0xd94c, + 0xc96d, + 0xf90e, + 0xe92f, + 0x99c8, + 0x89e9, + 0xb98a, + 0xa9ab, + 0x5844, + 0x4865, + 0x7806, + 0x6827, + 0x18c0, + 0x08e1, + 0x3882, + 0x28a3, + 0xcb7d, + 0xdb5c, + 0xeb3f, + 0xfb1e, + 0x8bf9, + 0x9bd8, + 0xabbb, + 0xbb9a, + 0x4a75, + 0x5a54, + 0x6a37, + 0x7a16, + 0x0af1, + 0x1ad0, + 0x2ab3, + 0x3a92, + 0xfd2e, + 0xed0f, + 0xdd6c, + 0xcd4d, + 0xbdaa, + 0xad8b, + 0x9de8, + 0x8dc9, + 0x7c26, + 0x6c07, + 0x5c64, + 0x4c45, + 0x3ca2, + 0x2c83, + 0x1ce0, + 0x0cc1, + 0xef1f, + 0xff3e, + 0xcf5d, + 0xdf7c, + 0xaf9b, + 0xbfba, + 0x8fd9, + 0x9ff8, + 0x6e17, + 0x7e36, + 0x4e55, + 0x5e74, + 0x2e93, + 0x3eb2, + 0x0ed1, + 0x1ef0 + ]; + + // 8位字节反转 + static int _reverse8(int data) { + int temp = 0; + for (int i = 0; i < 8; i++) { + temp |= ((data >> i) & 0x01) << (7 - i); + } + return temp; + } + + // 16位字反转 + static int _reverse16(int data) { + int temp = 0; + for (int i = 0; i < 16; i++) { + temp |= ((data >> i) & 0x0001) << (15 - i); + } + return temp; + } } diff --git a/lib/blue/sm4Encipher/sm4.dart b/lib/blue/sm4Encipher/sm4.dart index 38df45db..382cd5fa 100755 --- a/lib/blue/sm4Encipher/sm4.dart +++ b/lib/blue/sm4Encipher/sm4.dart @@ -263,7 +263,12 @@ class SM4 { 0x48 ]; - static const List FK = [0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC]; + static const List FK = [ + 0xA3B1BAC6, + 0x56AA3350, + 0x677D9197, + 0xB27022DC + ]; static const List CK = [ 0x00070e15, @@ -411,11 +416,27 @@ class SM4 { } return paddedList; } else { + // 解密时去除PKCS7填充 + final int lastByte = input.last; + if (lastByte > 0 && lastByte <= blockSize) { + // 验证填充是否合法 + bool isValidPadding = true; + for (int i = input.length - lastByte; i < input.length; i++) { + if (input[i] != lastByte) { + isValidPadding = false; + break; + } + } + if (isValidPadding) { + return input.sublist(0, input.length - lastByte); + } + } + return input; // final lastByte = input.last; // final cutLen = input.length - lastByte; - // AppLog.log("object input.length:${input.length} lastByte:$lastByte input:$input cutLen:$cutLen"); + // // AppLog.log("object input.length:${input.length} lastByte:$lastByte input:$input cutLen:$cutLen"); // return input.sublist(0, cutLen); - return input; + // return input; } } @@ -480,7 +501,8 @@ class SM4 { final List supplementList = List.filled(16, 0x00); /// complete list - final List completeList = [...list, ...supplementList].sublist(0, 16); + final List completeList = + [...list, ...supplementList].sublist(0, 16); return completeList; }