鸿蒙5 RFID门禁模拟器开发实战:手机模拟门禁卡与多设备同步 原创

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

鸿蒙5 RFID门禁模拟器开发实战:手机模拟门禁卡与多设备同步

一、项目概述与架构设计

本RFID门禁模拟器基于鸿蒙5的NFC和分布式能力实现,主要功能包括:
手机模拟门禁卡(读/写/模拟)

多设备间门禁卡数据同步

分布式门禁权限管理

安全加密通信

技术架构图

┌─────────────┐ ┌─────────────┐ ┌─────────────┐
手机设备 │ │ 平板设备 │ │ 门禁终端 │

┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐ │

│ 卡模拟 │─┼───▶│ │ 权限管理 │ │ │ │ 读卡器 │ │

└────────┘ │ │ └────────┘ │ │ └────────┘ │

└───────┬─────┘ └───────┬─────┘ └───────┬─────┘
│ │

    └─────────┬────────┴─────────┬────────┘

      ┌───────▼───────┐   ┌───────▼───────┐

分布式数据服务 │ │ 安全加密服务 │

      └───────────────┘   └───────────────┘

二、核心代码实现
NFC卡模拟服务

// RfidEmulatorService.ets
import nfc from ‘@ohos.nfc’;
import distributedData from ‘@ohos.data.distributedData’;

export class RfidEmulatorService {
private nfcController: nfc.NfcController;
private kvStore: distributedData.KVStore;
private readonly STORE_ID = ‘rfid_card_store’;

async init() {
// 初始化NFC控制器
this.nfcController = await nfc.getNfcController();

// 初始化分布式数据
const kvManager = await distributedData.createKVManager({
  bundleName: 'com.example.rfidemulator'
});
this.kvStore = await kvManager.getKVStore(this.STORE_ID, {
  createIfMissing: true,
  autoSync: true
});

async emulateCard(cardData: RfidCard): Promise<boolean> {

try {
  // 本地创建快捷方式
  await nfc.publishCardEmulation({
    id: cardData.id,
    techType: nfc.NfcTechType.ISO_14443_TYPE_A,
    data: this.encodeCardData(cardData)
  });
  
  // 同步到其他设备
  await this.kvStore.put(card_${cardData.id}, JSON.stringify({
    ...cardData,
    deviceId: deviceInfo.deviceId,
    timestamp: new Date().getTime()
  }));
  
  return true;

catch (err) {

  console.error('模拟卡片失败:', err);
  return false;

}

private encodeCardData(card: RfidCard): Uint8Array {
const encoder = new TextEncoder();
return encoder.encode(JSON.stringify({
uid: card.uid,
accessData: card.accessData
}));
subscribeCardUpdates(callback: (card: RfidCard) => void) {

this.kvStore.on('dataChange', distributedData.SubscribeType.SUBSCRIBE_TYPE_ALL, (changes) => {
  changes.forEach(change => {
    if (change.key.startsWith('card_')) {
      const data = JSON.parse(change.value);
      if (data.deviceId !== deviceInfo.deviceId) {
        callback(data);

}

  });
});

}

门禁卡数据管理

// CardManager.ets
import cryptoFramework from ‘@ohos.security.cryptoFramework’;

export class CardManager {
private cardList: RfidCard[] = [];
private crypto: CryptoService = new CryptoService();

async addCard(cardData: RfidCard) {
// 加密敏感数据
const encrypted = await this.crypto.encryptCardData(cardData);
this.cardList.push(encrypted);
return encrypted;
async getCard(uid: string): Promise<RfidCard | undefined> {

const card = this.cardList.find(c => c.uid === uid);
if (card) {
  return await this.crypto.decryptCardData(card);

}

async syncCardsToDevice(deviceId: string) {
const encryptedCards = await Promise.all(
this.cardList.map(async card => ({
…card,
deviceId,
timestamp: new Date().getTime()
}))
);

await this.kvStore.put('card_list', JSON.stringify(encryptedCards));

}

// 加密服务
class CryptoService {
async encryptCardData(card: RfidCard): Promise<EncryptedCard> {
const cipher = await cryptoFramework.createCipher(‘AES256/GCM/PKCS5Padding’);
const secretKey = await this.generateSecretKey(card.uid);

const iv = await this.generateIv();
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, secretKey, {
  iv: iv,
  authTag: true
});

const input = { data: JSON.stringify(card) };
const output = await cipher.doFinal(input);

return {
  cipherText: output.data,
  iv: iv,
  authTag: output.authTag,
  uid: card.uid // UID不加密
};

}

门禁模拟主界面

// RfidEmulatorPage.ets
@Entry
@Component
struct RfidEmulatorPage {
@State currentCard: RfidCard | null = null;
@State cardList: RfidCard[] = [];
@State connectedDevices: DeviceInfo[] = [];

private rfidService = new RfidEmulatorService();
private deviceService = new DeviceService();

aboutToAppear() {
this.rfidService.init();
this.deviceService.startDiscovery();
this.loadCards();

// 订阅卡数据更新
this.rfidService.subscribeCardUpdates(this.handleCardUpdate.bind(this));

build() {

Column() {
  // 设备连接状态
  DeviceStatusBar({ devices: this.connectedDevices })
  
  // 卡片选择器
  CardSelector({
    cards: this.cardList,
    onSelect: this.selectCard.bind(this)
  })
  
  // 当前激活卡片
  if (this.currentCard) {
    ActiveCardView({ card: this.currentCard })

// 添加按钮

  Button('添加门禁卡', { type: ButtonType.Capsule })
    .margin(20)
    .onClick(() => this.showAddDialog())

}

private async selectCard(card: RfidCard) {
this.currentCard = card;
await this.rfidService.emulateCard(card);
private handleCardUpdate(card: RfidCard) {

if (!this.cardList.some(c => c.id === card.id)) {
  this.cardList = [...this.cardList, card];

}

三、关键技术创新点
多设备卡数据同步

// 状态同步算法
private async syncExecutionStatus(cardId: string) {
const devices = await this.getScenarioDevices(cardId);
const statusList = await Promise.all(
devices.map(d => this.kvStore.get(card_status_{cardId}_{d}))
);

// 计算总体状态
const overallStatus = statusList.reduce((result, s) => {
const status = JSON.parse(s);
return {
active: result.active || status.active,
lastUsed: Math.max(result.lastUsed, status.timestamp)
};
}, { active: false, lastUsed: 0 });

// 更新全局状态
await this.kvStore.put(card_status_${cardId}_global, JSON.stringify({
…overallStatus,
timestamp: new Date().getTime()
}));

安全通信协议

// 安全通道建立
class SecureChannel {
private sessionKey: cryptoFramework.SymKey;

async establish(deviceId: string) {
// 1. 密钥交换
const ecdh = await cryptoFramework.createKeyAgreement(‘ECDH’);
const keyPair = await ecdh.generateKeyPair();

// 2. 共享密钥计算
const publicKey = await this.exchangePublicKeys(deviceId, keyPair.pubKey);
this.sessionKey = await ecdh.computeSecret(keyPair.priKey, publicKey);

async encryptMessage(message: string): Promise<EncryptedMessage> {

const cipher = await cryptoFramework.createCipher('AES256/GCM');
const iv = cryptoFramework.getRandomValues(new Uint8Array(12));

await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, this.sessionKey, { iv });
const output = await cipher.doFinal({ data: message });

return {
  cipherText: output.data,
  iv,
  authTag: output.authTag
};

}

动态权限管理

// 权限验证服务
class AccessControlService {
private accessRules: AccessRule[] = [];

async verifyAccess(card: RfidCard, terminalId: string): Promise<boolean> {
// 1. 检查本地规则
const localRule = this.accessRules.find(r =>
r.cardUid = card.uid && r.terminalId = terminalId
);

if (localRule) {
  return localRule.granted;

// 2. 查询分布式规则

const distributedRule = await this.queryDistributedRule(card.uid, terminalId);
if (distributedRule) {
  this.accessRules.push(distributedRule);
  return distributedRule.granted;

// 3. 默认拒绝

return false;

async syncAccessRules(deviceId: string) {

const rules = this.accessRules.filter(r => r.deviceId === deviceId);
await this.kvStore.put('access_rules', JSON.stringify(rules));

}

四、安全增强方案
卡数据加密存储

// 安全存储实现
class SecureStorage {
private context: Context;

async storeCard(card: EncryptedCard): Promise<void> {
const key = card_${card.uid};
await this.context.storage.setString(key, JSON.stringify(card));
async retrieveCard(uid: string): Promise<EncryptedCard | null> {

const data = await this.context.storage.getString(card_${uid});
return data ? JSON.parse(data) : null;

}

设备认证机制

// 设备认证服务
class DeviceAuthService {
private trustedDevices: string[] = [];

async authenticate(deviceId: string): Promise<boolean> {
if (this.trustedDevices.includes(deviceId)) {
return true;
// 发起PIN码验证

const result = await deviceManager.authenticateDevice(deviceId, {
  authType: 1, // PIN码认证
  extraInfo: {}
});

if (result === 0) { // 认证成功
  this.trustedDevices.push(deviceId);
  return true;

return false;

}

安全日志记录

// 审计日志服务
class AuditLogService {
async logAccessAttempt(cardUid: string, terminalId: string, granted: boolean) {
const logEntry = {
timestamp: new Date().getTime(),
cardUid,
terminalId,
granted,
deviceId: deviceInfo.deviceId
};

await this.kvStore.put(log_${Date.now()}, JSON.stringify(logEntry));

async syncLogs() {

const logs = await this.kvStore.getEntries('log_');
await this.cloudService.uploadLogs(logs);

}

五、完整UI组件实现
卡片列表组件

// CardListView.ets
@Component
struct CardListView {
@Prop cards: RfidCard[];
@Prop onSelect: (card: RfidCard) => void;

build() {
List() {
ForEach(this.cards, (card) => {
ListItem() {
CardItem({
card,
onClick: () => this.onSelect(card)
})
})

.height(‘60%’)

.divider({ strokeWidth: 1, color: '#F1F1F1' })

}

@Component
struct CardItem {
@Prop card: RfidCard;
@Prop onClick: () => void;

build() {
Row() {
Image(card.type === ‘admin’ ? ‘admin_card.png’ : ‘user_card.png’)
.width(40)
.height(40)

  Column() {
    Text(card.name)
      .fontSize(16)
    Text(UID: ${card.uid.substring(0, 8)}...)
      .fontSize(12)
      .opacity(0.7)

.layoutWeight(1)

  Image('arrow_right.png')
    .width(20)
    .height(20)

.padding(15)

.onClick(() => this.onClick())

}

读卡器模拟界面

// ReaderSimulator.ets
@Component
struct ReaderSimulator {
@State detectedCards: RfidCard[] = [];
private nfcReader: nfc.NfcReader;

build() {
Column() {
Text(‘门禁读卡器模拟’)
.fontSize(20)
.margin({ bottom: 20 })

  // 检测区域
  NFCField({
    onCardDetected: this.handleCardDetected.bind(this)
  })
  
  // 检测到的卡片
  if (this.detectedCards.length > 0) {
    DetectedCards({
      cards: this.detectedCards,
      onGrantAccess: this.grantAccess.bind(this)
    })

}

private async handleCardDetected(cardData: Uint8Array) {

const card = this.decodeCardData(cardData);
this.detectedCards = [...this.detectedCards, card];

// 验证访问权限
const granted = await accessControl.verifyAccess(card, deviceInfo.deviceId);
this.logAccessAttempt(card, granted);

}

六、项目部署与测试
权限配置

在module.json5中添加:

“requestPermissions”: [
“name”: “ohos.permission.NFC”

},
“name”: “ohos.permission.NFC_TAG”

},
“name”: “ohos.permission.DISTRIBUTED_DATASYNC”

},
“name”: “ohos.permission.ACCESS_USER_AUTH_INTERNAL”

]

测试方案

// 卡模拟测试
describe(‘CardEmulation’, () => {
it(‘should emulate RFID card correctly’, async () => {
const service = new RfidEmulatorService();
await service.init();

const testCard = {
  uid: 'A1B2C3D4',
  name: '测试卡',
  accessData: 'encrypted_data'
};

await service.emulateCard(testCard);
expect(service.isEmulating).toBe(true);

});
});

// 安全通信测试
describe(‘SecureChannel’, () => {
it(‘should encrypt and decrypt messages’, async () => {
const channel = new SecureChannel();
await channel.establish(‘test_device’);

const original = 'secret_data';
const encrypted = await channel.encryptMessage(original);
const decrypted = await channel.decryptMessage(encrypted);

expect(decrypted).toEqual(original);

});
});

七、总结与扩展

本方案实现了:
基于鸿蒙NFC的RFID卡模拟功能

多设备间门禁卡数据安全同步

分布式权限管理系统

端到端加密通信保障

扩展方向:
集成生物识别认证

开发门禁事件实时监控

支持访客临时卡功能

添加云端卡管理

鸿蒙的安全框架为隐私敏感型应用开发提供了坚实基础,开发者可基于此项目框架,进一步探索更多智能门禁场景的创新实现。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
收藏
回复
举报
回复
    相关推荐