fix:调整新的中继协议中的上报签名逻辑
This commit is contained in:
parent
fec9933c0a
commit
3a27c83c62
@ -235,13 +235,13 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
|
||||
: null)),
|
||||
SubmitBtn(
|
||||
btnName: '发送上线请求',
|
||||
onClick: () {
|
||||
onClick: () async {
|
||||
// 注册星图节点信息
|
||||
StartChartManage().clientRegister();
|
||||
await StartChartManage().clientRegister();
|
||||
// 查询中继信息
|
||||
StartChartManage().relayQuery();
|
||||
await StartChartManage().relayQuery();
|
||||
// 发送上线请求
|
||||
StartChartManage().onlineRelayService();
|
||||
await StartChartManage().onlineRelayService();
|
||||
},
|
||||
),
|
||||
SubmitBtn(
|
||||
|
||||
@ -289,4 +289,6 @@ abstract class Api {
|
||||
'/SL-A-1.0/relay/query'; // 星图--中继查询
|
||||
final String reportInformationDataURL =
|
||||
'/SL-A-1.0/peer/login'; // 星图--信息上报
|
||||
final String analyzeInformationOtherEndURL =
|
||||
'/SL-A-1.0/peer/nslookup'; // 星图--解析对端信息
|
||||
}
|
||||
|
||||
@ -55,4 +55,15 @@ class StartChartApi extends BaseProvider {
|
||||
isUserBaseUrl: false,
|
||||
);
|
||||
}
|
||||
|
||||
// 星图--解析对端信息
|
||||
Future<void> analyzeInformationOtherEnd({
|
||||
required String peerId,
|
||||
}) async {
|
||||
final response = await get(
|
||||
_startChartHost + analyzeInformationOtherEndURL.toUrl + '?id=$peerId',
|
||||
isUnShowLoading: true,
|
||||
isUserBaseUrl: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:convert/convert.dart';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:encrypt/encrypt.dart';
|
||||
import 'package:pointycastle/asymmetric/api.dart';
|
||||
import 'package:pointycastle/asn1/asn1_parser.dart';
|
||||
import 'package:pointycastle/asn1/primitives/asn1_integer.dart';
|
||||
import 'package:pointycastle/asn1/primitives/asn1_sequence.dart';
|
||||
import 'package:star_lock/app_settings/app_settings.dart';
|
||||
import 'package:star_lock/flavors.dart';
|
||||
import 'package:star_lock/network/start_chart_api.dart';
|
||||
@ -20,6 +18,12 @@ import 'package:star_lock/tools/deviceInfo_utils.dart';
|
||||
import 'package:star_lock/tools/storage.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:pointycastle/export.dart' as pc; // 为 Pointy Castle 添加命名空间
|
||||
import 'package:asn1lib/asn1lib.dart' as asn1lib; // Prefix for asn1lib
|
||||
|
||||
class StartChartManage {
|
||||
// 私有构造函数,防止外部直接new对象
|
||||
StartChartManage._internal();
|
||||
@ -225,7 +229,7 @@ class StartChartManage {
|
||||
// 生成签名
|
||||
final sign = await _generateSign(
|
||||
currentTimestamp: currentTimestamp,
|
||||
privateKey: privateKey,
|
||||
privateKeyHex: privateKey,
|
||||
);
|
||||
|
||||
// 获取本机所有ip地址和中继返回的外网地址
|
||||
@ -341,28 +345,127 @@ class StartChartManage {
|
||||
// 生成签名sing
|
||||
Future<String> _generateSign({
|
||||
required int currentTimestamp,
|
||||
required String privateKey,
|
||||
required String privateKeyHex,
|
||||
}) async {
|
||||
String resultSign = '';
|
||||
try {
|
||||
// 2. 将时间戳编码为小端字节序(Little Endian)
|
||||
// 1. 获取当前时间戳并编码为小端字节序
|
||||
Uint8List signData = Uint8List(4);
|
||||
signData.buffer
|
||||
.asByteData()
|
||||
ByteData.view(signData.buffer)
|
||||
.setUint32(0, currentTimestamp, Endian.little);
|
||||
|
||||
// 3. 使用 SHA-256 对 signData 进行哈希运算
|
||||
final sha256Hash = sha256.convert(signData);
|
||||
var parser = RSAKeyParser();
|
||||
final RSAPrivateKey parsePrivateKey =
|
||||
parser.parse('-----BEGIN RSA PRIVATE KEY-----\n' + privateKey)
|
||||
as RSAPrivateKey;
|
||||
// 2. 对时间戳数据计算 SHA-256 哈希值
|
||||
Digest hash = sha256.convert(signData);
|
||||
|
||||
// 3. 使用 RSA 私钥进行签名 (需要提供 RsaPrivateKey)
|
||||
pc.RSAPrivateKey privateKey =
|
||||
loadPrivateKey(privateKeyHex); // 需要加载你的 RSA 私钥
|
||||
Uint8List signature = rsaSign(privateKey, hash.bytes);
|
||||
|
||||
// 4. 将签名结果转换为十六进制字符串
|
||||
String hexSignature = signature
|
||||
.map((byte) => byte.toRadixString(16).padLeft(2, '0'))
|
||||
.join();
|
||||
resultSign = hexSignature;
|
||||
} catch (e) {
|
||||
_log(text: '❌--->生成签名时出现错误: $e');
|
||||
_log(text: '❌--->上报信息生成签名时出现错误: $e');
|
||||
}
|
||||
return resultSign ?? '';
|
||||
}
|
||||
|
||||
/// 自定义 PEM 格式的 RSA 私钥解析器
|
||||
pc.RSAPrivateKey loadPrivateKey(String privateKeyHex) {
|
||||
// 将十六进制字符串转换为字节数组
|
||||
final uint8list = Uint8List.fromList(hexToBytes(privateKeyHex));
|
||||
try {
|
||||
// 使用 asn1lib 的 ASN1Parser 解析
|
||||
final asn1Parser = asn1lib.ASN1Parser(uint8list);
|
||||
final topLevelSeq = asn1Parser.nextObject() as asn1lib.ASN1Sequence;
|
||||
|
||||
final modulus = bytesToBigInt(
|
||||
(topLevelSeq.elements[1] as asn1lib.ASN1Integer).valueBytes());
|
||||
final privateExponent = bytesToBigInt(
|
||||
(topLevelSeq.elements[3] as asn1lib.ASN1Integer).valueBytes());
|
||||
final p = bytesToBigInt(
|
||||
(topLevelSeq.elements[4] as asn1lib.ASN1Integer).valueBytes());
|
||||
final q = bytesToBigInt(
|
||||
(topLevelSeq.elements[5] as asn1lib.ASN1Integer).valueBytes());
|
||||
|
||||
return pc.RSAPrivateKey(modulus, privateExponent, p, q);
|
||||
} catch (e) {
|
||||
// 如果发生解码错误,打印错误信息
|
||||
print("Error decoding private key: $e");
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
// 解析对端数据
|
||||
Future<void> analyzeInformationOtherEnd() async {
|
||||
await StartChartApi.to.analyzeInformationOtherEnd(peerId: ToPeerId);
|
||||
}
|
||||
|
||||
// 将十六进制字符串转换为字节数组
|
||||
List<int> hexToBytes(String hex) {
|
||||
return List<int>.generate(hex.length ~/ 2,
|
||||
(i) => int.parse(hex.substring(i * 2, i * 2 + 2), radix: 16));
|
||||
}
|
||||
|
||||
BigInt bytesToBigInt(Uint8List bytes) {
|
||||
return BigInt.parse(
|
||||
bytes.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join(),
|
||||
radix: 16,
|
||||
);
|
||||
}
|
||||
|
||||
/// 使用 RSA 私钥进行 PKCS#1 v1.5 签名
|
||||
Uint8List rsaSign(pc.RSAPrivateKey privateKey, List<int> data) {
|
||||
final signer = pc.RSASigner(pc.SHA256Digest(), '06052b24030203')
|
||||
..init(true, pc.PrivateKeyParameter<pc.RSAPrivateKey>(privateKey));
|
||||
return signer.generateSignature(Uint8List.fromList(data)).bytes;
|
||||
}
|
||||
|
||||
// 解析 RSA 私钥
|
||||
// RSAPrivateKey parseRSAPrivateKey1(Uint8List bytes) {
|
||||
// // 这里假设私钥是以 PKCS#1 DER 编码的
|
||||
// ASN1Parser parser = ASN1Parser(bytes);
|
||||
// ASN1Sequence seq = parser.nextObject() as ASN1Sequence;
|
||||
// if (seq.elements == null || seq.elements!.length < 9) {
|
||||
// throw ArgumentError("Invalid RSA private key");
|
||||
// }
|
||||
//
|
||||
// // 解析各个元素
|
||||
// ASN1Integer version = seq.elements![0] as ASN1Integer;
|
||||
// ASN1Integer modulus = seq.elements![1] as ASN1Integer;
|
||||
// // ASN1Integer publicExponent = seq.elements![2] as ASN1Integer;
|
||||
// ASN1Integer privateExponent = seq.elements![3] as ASN1Integer;
|
||||
// ASN1Integer p = seq.elements![2] as ASN1Integer;
|
||||
// ASN1Integer q = seq.elements![4] as ASN1Integer;
|
||||
// ASN1Integer dP = seq.elements![5] as ASN1Integer;
|
||||
// ASN1Integer dQ = seq.elements![6] as ASN1Integer;
|
||||
// ASN1Integer qInv = seq.elements![7] as ASN1Integer;
|
||||
//
|
||||
// // 将 ASN1Integer 转换为 BigInt
|
||||
// BigInt modulusValue = _convertToBigInt(modulus);
|
||||
// // BigInt publicExponentValue = _convertToBigInt(publicExponent);
|
||||
// BigInt privateExponentValue = _convertToBigInt(privateExponent);
|
||||
// BigInt pValue = _convertToBigInt(p);
|
||||
// BigInt qValue = _convertToBigInt(q);
|
||||
// BigInt dPValue = _convertToBigInt(dP);
|
||||
// BigInt dQPValue = _convertToBigInt(dQ);
|
||||
// BigInt qInvQPValue = _convertToBigInt(qInv);
|
||||
//
|
||||
// // 创建 RSAPrivateKey 对象
|
||||
// return RSAPrivateKey(modulusValue, privateExponentValue, pValue, qValue);
|
||||
// }
|
||||
//
|
||||
// // 将 ASN1Integer 转换为 BigInt
|
||||
// BigInt _convertToBigInt(ASN1Integer integer) {
|
||||
// // 获取 ASN1Integer 的字节数据
|
||||
// Uint8List bytes = integer.valueBytes!;
|
||||
// // 将字节数据转换为 BigInt
|
||||
// return BigInt.parse(hex.encode(bytes), radix: 16);
|
||||
// }
|
||||
|
||||
Future<String> getPublicKey() async {
|
||||
// 从缓存中获取星图注册节点信息
|
||||
final StarChartRegisterNodeEntity? starChartRegisterNodeInfo =
|
||||
|
||||
@ -20,7 +20,7 @@ class CommandUDPReciverManager {
|
||||
if (dataSize < 4) {
|
||||
return;
|
||||
}
|
||||
// AppLog.log('appReceiveUDPData:$data');
|
||||
AppLog.log('appReceiveUDPData:$data');
|
||||
|
||||
final Uint8List data1 = Uint8List.fromList(data);
|
||||
if (data1.length == 1) {
|
||||
|
||||
@ -184,7 +184,7 @@ dependencies:
|
||||
#加密解密
|
||||
encrypt: ^5.0.1
|
||||
crypto: ^3.0.3
|
||||
pointycastle: ^3.3.0
|
||||
pointycastle: ^3.4.0
|
||||
date_format: ^2.0.7
|
||||
|
||||
# 下拉刷新
|
||||
@ -248,7 +248,8 @@ dependencies:
|
||||
open_filex: ^4.4.0
|
||||
|
||||
crc32_checksum: ^0.0.2
|
||||
fast_rsa: ^3.6.6
|
||||
cryptography: ^2.7.0
|
||||
asn1lib: ^1.0.0
|
||||
|
||||
|
||||
dependency_overrides:
|
||||
@ -256,6 +257,7 @@ dependency_overrides:
|
||||
google_maps_flutter_ios: 2.5.2
|
||||
flutter_plugin_android_lifecycle: 2.0.18
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user