
鸿蒙5 RFID门禁模拟器开发实战:手机模拟门禁卡与多设备同步 原创
鸿蒙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卡模拟功能
多设备间门禁卡数据安全同步
分布式权限管理系统
端到端加密通信保障
扩展方向:
集成生物识别认证
开发门禁事件实时监控
支持访客临时卡功能
添加云端卡管理
鸿蒙的安全框架为隐私敏感型应用开发提供了坚实基础,开发者可基于此项目框架,进一步探索更多智能门禁场景的创新实现。
