1. Android: 组合多个硬件标识 + 序列号 + Build信息
2. iOS: 组合设备型号 + 系统版本 + identifierForVendor,持久化存储到钥匙串 3. macOS: 使用硬件UUID + 序列号 4. Windows: 使用主板UUID + CPU信息 5. Linux: 使用machine-id + 硬件信息 (cherry picked from commit 1be3037f715548a1efa4cc5d7d204b989878557a)
This commit is contained in:
parent
c1c5f1a2e0
commit
5c8f0ca1fc
@ -1,6 +1,7 @@
|
||||
import 'dart:io';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_udid/flutter_udid.dart';
|
||||
import '../utils/kr_secure_storage.dart';
|
||||
import '../utils/kr_log_util.dart';
|
||||
import 'package:crypto/crypto.dart';
|
||||
@ -51,37 +52,28 @@ class KRDeviceInfoService {
|
||||
}
|
||||
|
||||
/// 获取设备唯一标识
|
||||
/// 使用多因子组合策略确保唯一性和稳定性
|
||||
Future<String> _getDeviceId() async {
|
||||
try {
|
||||
String? identifier;
|
||||
String identifier;
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
final androidInfo = await _deviceInfo.androidInfo;
|
||||
// Android使用androidId作为唯一标识
|
||||
identifier = androidInfo.id;
|
||||
identifier = await _getAndroidDeviceId();
|
||||
} else if (Platform.isIOS) {
|
||||
final iosInfo = await _deviceInfo.iosInfo;
|
||||
// iOS使用identifierForVendor作为唯一标识
|
||||
identifier = iosInfo.identifierForVendor;
|
||||
identifier = await _getIOSDeviceId();
|
||||
} else if (Platform.isMacOS) {
|
||||
final macInfo = await _deviceInfo.macOsInfo;
|
||||
// macOS使用systemGUID
|
||||
identifier = macInfo.systemGUID;
|
||||
identifier = await _getMacOSDeviceId();
|
||||
} else if (Platform.isWindows) {
|
||||
final windowsInfo = await _deviceInfo.windowsInfo;
|
||||
// Windows使用计算机名作为唯一标识
|
||||
identifier = windowsInfo.computerName;
|
||||
identifier = await _getWindowsDeviceId();
|
||||
} else if (Platform.isLinux) {
|
||||
final linuxInfo = await _deviceInfo.linuxInfo;
|
||||
// Linux使用machineId
|
||||
identifier = linuxInfo.machineId;
|
||||
identifier = await _getLinuxDeviceId();
|
||||
} else {
|
||||
// Web或其他平台,使用生成的UUID
|
||||
// Web或其他平台,使用生成的UUID
|
||||
identifier = await _getOrCreateStoredDeviceId();
|
||||
}
|
||||
|
||||
// 如果获取失败,使用存储的或生成新的ID
|
||||
if (identifier == null || identifier.isEmpty) {
|
||||
// 如果获取失败,使用存储的或生成新的ID
|
||||
if (identifier.isEmpty) {
|
||||
identifier = await _getOrCreateStoredDeviceId();
|
||||
}
|
||||
|
||||
@ -89,11 +81,201 @@ class KRDeviceInfoService {
|
||||
} catch (e) {
|
||||
print('❌ 获取设备ID失败: $e');
|
||||
KRLogUtil.kr_e('❌ 获取设备ID失败 - $e', tag: 'KRDeviceInfoService');
|
||||
// 如果获取失败,返回存储的或生成新的ID
|
||||
// 如果获取失败,返回存储的或生成新的ID
|
||||
return await _getOrCreateStoredDeviceId();
|
||||
}
|
||||
}
|
||||
|
||||
/// Android设备ID - 多因子组合
|
||||
/// 组合: AndroidID + 设备型号 + 主板信息 + 硬件信息
|
||||
Future<String> _getAndroidDeviceId() async {
|
||||
try {
|
||||
final androidInfo = await _deviceInfo.androidInfo;
|
||||
|
||||
// 优先使用 flutter_udid (封装了多种Android标识获取方式)
|
||||
String udid = await FlutterUdid.consistentUdid;
|
||||
|
||||
// 构建多因子字符串
|
||||
final factors = [
|
||||
udid,
|
||||
androidInfo.id, // Android ID
|
||||
androidInfo.board, // 主板
|
||||
androidInfo.bootloader, // Bootloader
|
||||
androidInfo.brand, // 品牌
|
||||
androidInfo.device, // 设备名
|
||||
androidInfo.fingerprint, // 系统指纹
|
||||
androidInfo.hardware, // 硬件名
|
||||
androidInfo.manufacturer, // 制造商
|
||||
androidInfo.model, // 型号
|
||||
androidInfo.product, // 产品名
|
||||
];
|
||||
|
||||
// 过滤空值并组合
|
||||
final combined = factors
|
||||
.where((f) => f != null && f.isNotEmpty)
|
||||
.join('|');
|
||||
|
||||
// 生成SHA256哈希
|
||||
final bytes = utf8.encode(combined);
|
||||
final hash = sha256.convert(bytes);
|
||||
|
||||
print('📱 Android多因子ID生成 - 因子数: ${factors.where((f) => f != null && f.isNotEmpty).length}');
|
||||
KRLogUtil.kr_i('📱 Android多因子ID - $hash', tag: 'KRDeviceInfoService');
|
||||
|
||||
return hash.toString();
|
||||
} catch (e) {
|
||||
print('❌ Android设备ID获取失败: $e');
|
||||
KRLogUtil.kr_e('❌ Android设备ID获取失败 - $e', tag: 'KRDeviceInfoService');
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/// iOS设备ID - 优先使用identifierForVendor,配合持久化存储
|
||||
/// iOS限制较严,无法获取IMEI等敏感信息
|
||||
Future<String> _getIOSDeviceId() async {
|
||||
try {
|
||||
final iosInfo = await _deviceInfo.iosInfo;
|
||||
|
||||
// 优先使用 flutter_udid
|
||||
String udid = await FlutterUdid.consistentUdid;
|
||||
|
||||
// 构建多因子字符串
|
||||
final factors = [
|
||||
udid,
|
||||
iosInfo.identifierForVendor ?? '', // Vendor标识
|
||||
iosInfo.model, // 型号
|
||||
iosInfo.systemName, // 系统名
|
||||
iosInfo.systemVersion, // 系统版本
|
||||
iosInfo.name, // 设备名(如"iPhone 14 Pro")
|
||||
iosInfo.utsname.machine, // 机器类型
|
||||
];
|
||||
|
||||
final combined = factors
|
||||
.where((f) => f.isNotEmpty)
|
||||
.join('|');
|
||||
|
||||
final bytes = utf8.encode(combined);
|
||||
final hash = sha256.convert(bytes);
|
||||
|
||||
print('📱 iOS多因子ID生成 - 因子数: ${factors.where((f) => f.isNotEmpty).length}');
|
||||
KRLogUtil.kr_i('📱 iOS多因子ID - $hash', tag: 'KRDeviceInfoService');
|
||||
|
||||
return hash.toString();
|
||||
} catch (e) {
|
||||
print('❌ iOS设备ID获取失败: $e');
|
||||
KRLogUtil.kr_e('❌ iOS设备ID获取失败 - $e', tag: 'KRDeviceInfoService');
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/// macOS设备ID - 使用硬件UUID
|
||||
Future<String> _getMacOSDeviceId() async {
|
||||
try {
|
||||
final macInfo = await _deviceInfo.macOsInfo;
|
||||
|
||||
// 优先使用 flutter_udid
|
||||
String udid = await FlutterUdid.consistentUdid;
|
||||
|
||||
// 构建多因子字符串
|
||||
final factors = [
|
||||
udid,
|
||||
macInfo.systemGUID ?? '', // 系统GUID (最稳定)
|
||||
macInfo.model, // 型号
|
||||
macInfo.hostName, // 主机名
|
||||
macInfo.arch, // 架构
|
||||
macInfo.kernelVersion, // 内核版本
|
||||
];
|
||||
|
||||
final combined = factors
|
||||
.where((f) => f.isNotEmpty)
|
||||
.join('|');
|
||||
|
||||
final bytes = utf8.encode(combined);
|
||||
final hash = sha256.convert(bytes);
|
||||
|
||||
print('📱 macOS多因子ID生成 - 因子数: ${factors.where((f) => f.isNotEmpty).length}');
|
||||
KRLogUtil.kr_i('📱 macOS多因子ID - $hash', tag: 'KRDeviceInfoService');
|
||||
|
||||
return hash.toString();
|
||||
} catch (e) {
|
||||
print('❌ macOS设备ID获取失败: $e');
|
||||
KRLogUtil.kr_e('❌ macOS设备ID获取失败 - $e', tag: 'KRDeviceInfoService');
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/// Windows设备ID - 使用机器GUID
|
||||
Future<String> _getWindowsDeviceId() async {
|
||||
try {
|
||||
final windowsInfo = await _deviceInfo.windowsInfo;
|
||||
|
||||
// 优先使用 flutter_udid
|
||||
String udid = await FlutterUdid.consistentUdid;
|
||||
|
||||
// 构建多因子字符串
|
||||
final factors = [
|
||||
udid,
|
||||
windowsInfo.deviceId, // 设备ID
|
||||
windowsInfo.computerName, // 计算机名
|
||||
windowsInfo.productName, // 产品名
|
||||
windowsInfo.numberOfCores.toString(), // CPU核心数
|
||||
windowsInfo.systemMemoryInMegabytes.toString(), // 内存大小
|
||||
];
|
||||
|
||||
final combined = factors
|
||||
.where((f) => f.isNotEmpty)
|
||||
.join('|');
|
||||
|
||||
final bytes = utf8.encode(combined);
|
||||
final hash = sha256.convert(bytes);
|
||||
|
||||
print('📱 Windows多因子ID生成 - 因子数: ${factors.where((f) => f.isNotEmpty).length}');
|
||||
KRLogUtil.kr_i('📱 Windows多因子ID - $hash', tag: 'KRDeviceInfoService');
|
||||
|
||||
return hash.toString();
|
||||
} catch (e) {
|
||||
print('❌ Windows设备ID获取失败: $e');
|
||||
KRLogUtil.kr_e('❌ Windows设备ID获取失败 - $e', tag: 'KRDeviceInfoService');
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/// Linux设备ID - 使用machine-id
|
||||
Future<String> _getLinuxDeviceId() async {
|
||||
try {
|
||||
final linuxInfo = await _deviceInfo.linuxInfo;
|
||||
|
||||
// 优先使用 flutter_udid
|
||||
String udid = await FlutterUdid.consistentUdid;
|
||||
|
||||
// 构建多因子字符串
|
||||
final factors = [
|
||||
udid,
|
||||
linuxInfo.machineId ?? '', // Machine ID (最稳定)
|
||||
linuxInfo.id, // 发行版ID
|
||||
linuxInfo.name, // 发行版名称
|
||||
linuxInfo.version ?? '', // 版本
|
||||
linuxInfo.variant ?? '', // 变体
|
||||
];
|
||||
|
||||
final combined = factors
|
||||
.where((f) => f.isNotEmpty)
|
||||
.join('|');
|
||||
|
||||
final bytes = utf8.encode(combined);
|
||||
final hash = sha256.convert(bytes);
|
||||
|
||||
print('📱 Linux多因子ID生成 - 因子数: ${factors.where((f) => f.isNotEmpty).length}');
|
||||
KRLogUtil.kr_i('📱 Linux多因子ID - $hash', tag: 'KRDeviceInfoService');
|
||||
|
||||
return hash.toString();
|
||||
} catch (e) {
|
||||
print('❌ Linux设备ID获取失败: $e');
|
||||
KRLogUtil.kr_e('❌ Linux设备ID获取失败 - $e', tag: 'KRDeviceInfoService');
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取或创建存储的设备ID
|
||||
Future<String> _getOrCreateStoredDeviceId() async {
|
||||
try {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user