鸿蒙5 Wi-Fi安全扫描工具开发指南 原创

进修的泡芙
发布于 2025-6-20 14:16
浏览
0收藏

鸿蒙5 Wi-Fi安全扫描工具开发指南

一、项目概述

本文基于HarmonyOS 5的Wi-Fi管理能力和分布式技术,开发一款Wi-Fi安全扫描工具,借鉴《鸿蒙跨端U同步》中游戏多设备同步的技术原理,实现多设备协同的Wi-Fi网络安全检测系统。该工具能够扫描周围Wi-Fi网络,识别潜在风险(如弱密码、开放网络、WPS等),并通过分布式能力实现多设备间的扫描结果同步和告警。

二、系统架构

±--------------------+ ±--------------------+ ±--------------------+
主控设备 <-----> 分布式数据总线 <-----> 从属扫描设备
(Controller Device) (Distributed Bus) (Scanner Device)
±---------±---------+ ±---------±---------+ ±---------±---------+

±---------v----------+ ±---------v----------+ ±---------v----------+
安全分析引擎 风险同步服务 Wi-Fi扫描模块
(Security Engine) (Sync Service) (WiFi Scanner)

±--------------------+ ±--------------------+ ±--------------------+

三、核心代码实现
Wi-Fi网络数据模型

// src/main/ets/model/WifiNetworkModel.ts
export class WifiNetworkInfo {
ssid: string; // 网络SSID
bssid: string; // BSSID(MAC地址)
securityType: number; // 安全类型
rssi: number; // 信号强度
frequency: number; // 频率(2.4G/5G)
timestamp: number; // 发现时间戳
isHidden: boolean; // 是否隐藏网络
risks: WifiRisk[]; // 风险列表
deviceId: string; // 发现设备ID

constructor(scanResult: wifi.ScanResult) {
this.ssid = scanResult.ssid || ‘隐藏网络’;
this.bssid = scanResult.bssid;
this.securityType = scanResult.securityType;
this.rssi = scanResult.rssi;
this.frequency = scanResult.frequency;
this.timestamp = Date.now();
this.isHidden = !scanResult.ssid;
this.risks = [];
this.deviceId = ‘’;
addRisk(risk: WifiRisk): void {

if (!this.risks.some(r => r.type === risk.type)) {
  this.risks.push(risk);

}

toJson(): string {
return JSON.stringify({
ssid: this.ssid,
bssid: this.bssid,
securityType: this.securityType,
rssi: this.rssi,
frequency: this.frequency,
timestamp: this.timestamp,
isHidden: this.isHidden,
risks: this.risks,
deviceId: this.deviceId
});
static fromJson(jsonStr: string): WifiNetworkInfo {

const json = JSON.parse(jsonStr);
const info = new WifiNetworkInfo({
  ssid: json.ssid,
  bssid: json.bssid,
  securityType: json.securityType,
  rssi: json.rssi,
  frequency: json.frequency
});
info.timestamp = json.timestamp;
info.isHidden = json.isHidden;
info.risks = json.risks;
info.deviceId = json.deviceId;
return info;

}

export type WifiRisk = {
type: WifiRiskType;
level: ‘low’ ‘medium’
‘high’;
description: string;
};

export enum WifiRiskType {
OPEN_NETWORK = ‘OPEN_NETWORK’,
WEAK_ENCRYPTION = ‘WEAK_ENCRYPTION’,
WPS_ENABLED = ‘WPS_ENABLED’,
ROGUE_AP = ‘ROGUE_AP’,
KNOWN_VULNERABILITY = ‘KNOWN_VULNERABILITY’

分布式同步服务

// src/main/ets/service/DistributedSyncService.ts
import { distributedData } from ‘@ohos.data.distributedData’;
import { BusinessError } from ‘@ohos.base’;
import { WifiNetworkInfo } from ‘…/model/WifiNetworkModel’;
import { deviceManager } from ‘@ohos.distributedDeviceManager’;

export class DistributedSyncService {
private static instance: DistributedSyncService;
private kvManager: distributedData.KVManager;
private kvStore: distributedData.KVStore;
private readonly STORE_ID = ‘wifi_scan_store’;
private readonly SYNC_KEY_PREFIX = ‘wifi_’;
private subscribers: ((data: WifiNetworkInfo) => void)[] = [];

private constructor() {
this.initDistributedData();
public static getInstance(): DistributedSyncService {

if (!DistributedSyncService.instance) {
  DistributedSyncService.instance = new DistributedSyncService();

return DistributedSyncService.instance;

private initDistributedData(): void {

const config: distributedData.KVManagerConfig = {
  bundleName: 'com.example.wifiscanner',
  userInfo: {
    userId: '0',
    userType: distributedData.UserType.SAME_USER_ID

};

try {
  distributedData.createKVManager(config, (err: BusinessError, manager: distributedData.KVManager) => {
    if (err) {
      console.error(Failed to create KVManager. Code: {err.code}, message: {err.message});
      return;

this.kvManager = manager;

    const options: distributedData.Options = {
      createIfMissing: true,
      encrypt: false, // 安全数据不需要额外加密
      backup: false,
      autoSync: true,
      kvStoreType: distributedData.KVStoreType.SINGLE_VERSION,
      schema: '',
      securityLevel: distributedData.SecurityLevel.S1
    };

    this.kvManager.getKVStore(this.STORE_ID, options, (err: BusinessError, store: distributedData.KVStore) => {
      if (err) {
        console.error(Failed to get KVStore. Code: {err.code}, message: {err.message});
        return;

this.kvStore = store;

      this.registerDataListener();
    });
  });

catch (e) {

  console.error(An unexpected error occurred. Code: {e.code}, message: {e.message});

}

private registerDataListener(): void {
try {
this.kvStore.on(‘dataChange’, distributedData.SubscribeType.SUBSCRIBE_TYPE_ALL, (data: distributedData.ChangeData) => {
if (data.key.startsWith(this.SYNC_KEY_PREFIX)) {
const networkInfo = WifiNetworkInfo.fromJson(data.value.value as string);
this.notifySubscribers(networkInfo);
});

catch (e) {

  console.error(Failed to register data listener. Code: {e.code}, message: {e.message});

}

public subscribe(callback: (data: WifiNetworkInfo) => void): void {
this.subscribers.push(callback);
public unsubscribe(callback: (data: WifiNetworkInfo) => void): void {

this.subscribers = this.subscribers.filter(sub => sub !== callback);

private notifySubscribers(data: WifiNetworkInfo): void {

this.subscribers.forEach(callback => callback(data));

public syncNetworkInfo(data: WifiNetworkInfo): void {

if (!this.kvStore) {
  console.error('KVStore is not initialized');
  return;

deviceManager.getLocalDeviceInfo((err: BusinessError, info) => {

  if (err) {
    console.error(Failed to get device info. Code: {err.code}, message: {err.message});
    return;

data.deviceId = info.deviceId;

  const key = this.SYNC_KEY_PREFIX + data.bssid;

  try {
    this.kvStore.put(key, data.toJson(), (err: BusinessError) => {
      if (err) {
        console.error(Failed to put data. Code: {err.code}, message: {err.message});

});

catch (e) {

    console.error(An unexpected error occurred. Code: {e.code}, message: {e.message});

});

public async getAllNetworks(): Promise<WifiNetworkInfo[]> {

return new Promise((resolve) => {
  if (!this.kvStore) {
    resolve([]);
    return;

try {

    const query: distributedData.Query = {
      prefixKey: this.SYNC_KEY_PREFIX
    };

    this.kvStore.getEntries(query, (err: BusinessError, entries: distributedData.Entry[]) => {
      if (err) {
        console.error(Failed to get entries. Code: {err.code}, message: {err.message});
        resolve([]);
        return;

const networks = entries.map(entry =>

        WifiNetworkInfo.fromJson(entry.value.value as string)
      );
      resolve(networks);
    });

catch (e) {

    console.error(An unexpected error occurred. Code: {e.code}, message: {e.message});
    resolve([]);

});

}

Wi-Fi扫描与安全分析服务

// src/main/ets/service/WifiScannerService.ts
import { wifi } from ‘@ohos.wifiManager’;
import { BusinessError } from ‘@ohos.base’;
import { WifiNetworkInfo, WifiRisk, WifiRiskType } from ‘…/model/WifiNetworkModel’;
import { DistributedSyncService } from ‘./DistributedSyncService’;
import { deviceManager } from ‘@ohos.distributedDeviceManager’;

export class WifiScannerService {
private static instance: WifiScannerService;
private syncService = DistributedSyncService.getInstance();
private scanInterval: number = 0;
private knownRogueAPs: string[] = [
‘00:11:22:33:44:55’, // 示例恶意AP
‘66:77:88:99:aa:bb’
];

private constructor() {
this.initWifi();
public static getInstance(): WifiScannerService {

if (!WifiScannerService.instance) {
  WifiScannerService.instance = new WifiScannerService();

return WifiScannerService.instance;

private initWifi(): void {

try {
  wifi.on('wifiStateChange', (state: number) => {
    console.log(Wi-Fi状态变化: ${state});
  });

  wifi.on('wifiConnectionChange', (info: wifi.WifiConnectionInfo) => {
    console.log(Wi-Fi连接变化: ${JSON.stringify(info)});
  });

  wifi.on('wifiScanStateChange', (state: number) => {
    console.log(Wi-Fi扫描状态变化: ${state});
  });

catch (e) {

  console.error(初始化Wi-Fi监听器失败. Code: {e.code}, message: {e.message});

}

public startScanning(interval: number = 30000): void {
this.scanInterval = setInterval(() => {
this.performScan();
}, interval);

// 立即执行第一次扫描
this.performScan();

public stopScanning(): void {

if (this.scanInterval) {
  clearInterval(this.scanInterval);
  this.scanInterval = 0;

}

private performScan(): void {
try {
wifi.scan((err: BusinessError) => {
if (err) {
console.error(启动扫描失败. Code: {err.code}, message: {err.message});
return;
// 获取扫描结果

    const scanResults = wifi.getScanResults();
    scanResults.forEach(result => {
      const networkInfo = new WifiNetworkInfo(result);
      this.analyzeNetwork(networkInfo);
      this.syncService.syncNetworkInfo(networkInfo);
    });
  });

catch (e) {

  console.error(发生意外错误. Code: {e.code}, message: {e.message});

}

private analyzeNetwork(network: WifiNetworkInfo): void {
// 检测开放网络
if (network.securityType === wifi.WifiSecurityType.OPEN) {
network.addRisk({
type: WifiRiskType.OPEN_NETWORK,
level: ‘high’,
description: ‘这是一个开放网络,所有通信都不加密’
});
// 检测弱加密(WEP)

if (network.securityType === wifi.WifiSecurityType.WEP) {
  network.addRisk({
    type: WifiRiskType.WEAK_ENCRYPTION,
    level: 'high',
    description: 'WEP加密已被证明不安全'
  });

// 检测WPS启用状态(模拟)

if (Math.random() > 0.7) { // 
  network.addRisk({
    type: WifiRiskType.WPS_ENABLED,
    level: 'medium',
    description: 'WPS功能已启用,
  });

// 检测已知恶意AP

if (this.knownRogueAPs.includes(network.bssid.toLowerCase())) {
  network.addRisk({
    type: WifiRiskType.ROGUE_AP,
    level: 'high',
    description: '已知的恶意接入点,
  });

// 检测信号强度异常(可能为蜜罐)

if (network.rssi > -40 && network.securityType === wifi.WifiSecurityType.OPEN) {
  network.addRisk({
    type: WifiRiskType.ROGUE_AP,
    level: 'medium',
    description: '强信号的开放网络可能是蜜罐'
  });

}

public async getCurrentNetworks(): Promise<WifiNetworkInfo[]> {
try {
const scanResults = wifi.getScanResults();
return scanResults.map(result => {
const network = new WifiNetworkInfo(result);
this.analyzeNetwork(network);
return network;
});
catch (e) {

  console.error(获取扫描结果失败. Code: {e.code}, message: {e.message});
  return [];

}

主控设备界面

// src/main/ets/pages/ControllerView.ets
import { WifiNetworkInfo, WifiRiskType } from ‘…/model/WifiNetworkModel’;
import { WifiScannerService } from ‘…/service/WifiScannerService’;
import { DistributedSyncService } from ‘…/service/DistributedSyncService’;

@Entry
@Component
struct ControllerView {
@State networks: WifiNetworkInfo[] = [];
@State isScanning: boolean = false;
@State selectedNetwork: WifiNetworkInfo | null = null;
private scanner = WifiScannerService.getInstance();
private syncService = DistributedSyncService.getInstance();

aboutToAppear(): void {
this.syncService.subscribe(this.handleNetworkUpdate.bind(this));
this.loadAllNetworks();
aboutToDisappear(): void {

this.syncService.unsubscribe(this.handleNetworkUpdate.bind(this));

private handleNetworkUpdate(network: WifiNetworkInfo): void {

const index = this.networks.findIndex(n => n.bssid === network.bssid);
if (index >= 0) {
  this.networks[index] = network;

else {

  this.networks.unshift(network);

this.networks = […this.networks]; // 触发状态更新

private async loadAllNetworks(): Promise<void> {

this.networks = await this.syncService.getAllNetworks();

private toggleScanning(): void {

if (this.isScanning) {
  this.scanner.stopScanning();

else {

  this.scanner.startScanning();

this.isScanning = !this.isScanning;

private getRiskColor(level: string): ResourceColor {

switch (level) {
  case 'high': return '#FF5252';
  case 'medium': return '#FF9800';
  case 'low': return '#FFC107';
  default: return '#9E9E9E';

}

private getRiskIcon(type: WifiRiskType): string {
switch (type) {
case WifiRiskType.OPEN_NETWORK: return ‘resources/unlock.png’;
case WifiRiskType.WEAK_ENCRYPTION: return ‘resources/shield.png’;
case WifiRiskType.WPS_ENABLED: return ‘resources/wps.png’;
case WifiRiskType.ROGUE_AP: return ‘resources/rogue.png’;
case WifiRiskType.KNOWN_VULNERABILITY: return ‘resources/bug.png’;
default: return ‘resources/info.png’;
}

build() {
Column() {
// 标题和控制按钮
Row() {
Text(‘Wi-Fi安全扫描’)
.fontSize(24)
.fontWeight(FontWeight.Bold)

    Button(this.isScanning ? '停止扫描' : '开始扫描')
      .margin({left: 20})
      .onClick(() => this.toggleScanning())

.width(‘100%’)

  .justifyContent(FlexAlign.Center)
  .margin({bottom: 20})

  // 网络列表
  List({ space: 10 }) {
    ForEach(this.networks, (network: WifiNetworkInfo) => {
      ListItem() {
        Column() {
          Row() {
            Text(network.ssid)
              .fontSize(18)
              .fontWeight(FontWeight.Bold)
            
            Text(信号: ${network.rssi}dBm)
              .fontSize(14)
              .margin({left: 10})

Row() {

            if (network.risks.length > 0) {
              ForEach(network.risks, (risk: WifiRisk) => {
                Image(this.getRiskIcon(risk.type))
                  .width(20)
                  .height(20)
                  .margin({right: 5})
              })

else {

              Text('安全')
                .fontColor('#4CAF50')

Text(发现设备: ${network.deviceId.substring(0, 6)})

              .fontSize(12)
              .opacity(0.7)
              .margin({left: 10})

.margin({top: 5})

.width(‘100%’)

        .padding(10)
        .borderRadius(10)
        .backgroundColor(this.selectedNetwork?.bssid === network.bssid ? '#E3F2FD' : '#FAFAFA')

.onClick(() => {

        this.selectedNetwork = network;
      })
    })

.width(‘100%’)

  .layoutWeight(1)

  // 详情面板
  if (this.selectedNetwork) {
    Column() {
      Text(this.selectedNetwork.ssid)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
      
      Row() {
        Text(BSSID: ${this.selectedNetwork.bssid})
          .fontSize(14)
          .opacity(0.7)
        
        Text(频率: ${this.selectedNetwork.frequency > 5000 ? '5GHz' : '2.4GHz'})
          .fontSize(14)
          .opacity(0.7)
          .margin({left: 10})

.margin({top: 5})

      if (this.selectedNetwork.risks.length > 0) {
        Text('发现的安全风险:')
          .fontSize(16)
          .margin({top: 15})
        
        ForEach(this.selectedNetwork.risks, (risk: WifiRisk) => {
          Row() {
            Image(this.getRiskIcon(risk.type))
              .width(24)
              .height(24)
              .margin({right: 10})
            
            Column() {
              Text(risk.description)
                .fontSize(14)
              
              Text(风险等级: ${risk.level})
                .fontSize(12)
                .fontColor(this.getRiskColor(risk.level))

}

          .width('100%')
          .padding(10)
          .margin({top: 5})
          .borderRadius(5)
          .backgroundColor('#FFF3E0')
        })

else {

        Text('未发现已知安全风险')
          .fontSize(16)
          .fontColor('#4CAF50')
          .margin({top: 15})

}

    .width('100%')
    .padding(15)
    .margin({top: 10})
    .borderRadius(10)
    .backgroundColor('#FFFFFF')
    .shadow({ radius: 5, color: '#E0E0E0', offsetX: 0, offsetY: 2 })

}

.width('100%')
.height('100%')
.padding(15)
.backgroundColor('#F5F5F5')

}

从属扫描设备界面

// src/main/ets/pages/ScannerView.ets
import { WifiScannerService } from ‘…/service/WifiScannerService’;

@Entry
@Component
struct ScannerView {
@State isScanning: boolean = false;
@State lastScanTime: string = ‘从未扫描’;
private scanner = WifiScannerService.getInstance();

private toggleScanning(): void {
if (this.isScanning) {
this.scanner.stopScanning();
else {

  this.scanner.startScanning();
  this.lastScanTime = new Date().toLocaleTimeString();

this.isScanning = !this.isScanning;

build() {

Column() {
  Text('Wi-Fi扫描器')
    .fontSize(24)
    .fontWeight(FontWeight.Bold)
    .margin({bottom: 30})
  
  Image(this.isScanning ? 'resources/scan_active.png' : 'resources/scan_idle.png')
    .width(120)
    .height(120)
    .margin({bottom: 20})
  
  Text(this.isScanning ? '正在扫描附近Wi-Fi...' : '准备扫描')
    .fontSize(18)
    .margin({bottom: 5})
  
  Text(上次扫描: ${this.lastScanTime})
    .fontSize(14)
    .opacity(0.7)
    .margin({bottom: 30})
  
  Button(this.isScanning ? '停止扫描' : '开始扫描')
    .width(200)
    .height(50)
    .fontSize(18)
    .onClick(() => this.toggleScanning())
  
  Text('扫描结果将自动同步到主控设备')
    .fontSize(14)
    .opacity(0.7)
    .margin({top: 30})

.width(‘100%’)

.height('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.backgroundColor('#212121')

}

四、与游戏同步技术的结合点
实时数据同步机制:借鉴游戏中玩家状态同步技术,实现Wi-Fi扫描结果的实时同步

分布式设备发现:使用游戏中的设备发现机制自动组建扫描网络

数据聚合处理:类似游戏中的多玩家数据聚合,合并多设备的扫描结果

角色分工:主控设备与从属设备的分工协作,类似游戏中的主机与客户端

状态同步:保持各设备的扫描状态同步,类似游戏中的准备状态同步

五、关键特性实现
多设备协同扫描:

  // 协调多设备扫描时间

deviceManager.getTrustedDeviceList((err, devices) => {
if (!err && devices.length > 0) {
// 错开扫描时间避免冲突
const delay = Math.random() * 5000;
setTimeout(() => this.performScan(), delay);
});

风险数据库:

  // 加载已知风险AP数据库

import { dataStorage } from ‘@ohos.data.storage’;

const storage = await dataStorage.getStorage(‘riskdb’);
const rogueAPs = await storage.get(‘rogue_aps’, ‘[]’);
this.knownRogueAPs = JSON.parse(rogueAPs);

信号指纹分析:

  // 检测信号指纹异常(可能为克隆AP)

analyzeSignalFingerprint(network: WifiNetworkInfo): void {
const fingerprint = {network.bssid}{network.channel}${network.rssi};
if (this.knownFingerprints.has(fingerprint)) {
network.addRisk({
type: WifiRiskType.ROGUE_AP,
level: ‘high’,
description: ‘检测到信号指纹异常,可能是克隆AP’
});
}

隐私保护:

  // 匿名化处理扫描数据

anonymizeNetworkData(network: WifiNetworkInfo): void {
if (this.settings.anonymousMode) {
network.ssid = network.isHidden ? ‘隐藏网络’ : ‘匿名网络’;
network.bssid = ‘xx:xx:xx:’ + network.bssid.substring(8);
}

六、性能优化策略
智能扫描间隔:

  // 根据网络环境动态调整扫描频率

if (this.networks.length > 10) {
this.scanInterval = 60000; // 高密度区域降低频率
else {

 this.scanInterval = 30000; // 低密度区域提高频率

数据压缩传输:

  // 压缩扫描结果数据

import { zlib } from ‘@ohos.zlib’;

const compressed = zlib.deflateSync(JSON.stringify(scanResults));
this.syncService.syncCompressedData(compressed);

差异化设备处理:

  // 根据设备类型分配不同任务

if (device.deviceType === ‘phone’) {
this.enableDeepAnalysis(); // 手机执行深度分析
else {

 this.basicScanOnly(); // 其他设备执行基础扫描

后台扫描优化:

  // 后台模式降低资源占用

import { backgroundTaskManager } from ‘@ohos.backgroundTaskManager’;

backgroundTaskManager.startBackgroundRunning({
wantAgent: wantAgent,
backgroundMode: backgroundTaskManager.BackgroundMode.DATA_TRANSFER
}).then(() => {
this.lowPowerScanMode();
});

七、项目扩展方向
企业版功能:增加企业网络合规性检查

历史趋势分析:记录历史数据检测异常网络变化

自动化报告:生成PDF/HTML格式的安全报告

智能家居集成:自动隔离不安全的IoT设备

扫描:集成常见路由器
八、总结

本Wi-Fi安全扫描工具实现了以下核心功能:
多设备协同的Wi-Fi网络扫描

实时的安全风险检测与分析

扫描结果的分布式同步与聚合

直观的风险可视化展示

设备间的角色分工与协作

通过借鉴游戏中的多设备同步技术,我们构建了一个高效、可靠的Wi-Fi安全扫描系统。该项目展示了HarmonyOS分布式能力在网络安全领域的创新应用,为开发者提供了实现多设备协同安全工具的参考方案。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2025-6-20 14:20:08修改
收藏
回复
举报
回复
    相关推荐