
鸿蒙5生物认证加密日记本开发实战 原创
鸿蒙5生物认证加密日记本开发实战
一、项目概述与架构设计
本日记本应用基于鸿蒙5的生物认证和加密技术实现,主要功能包括:
人脸/指纹生物认证登录
日记内容本地加密存储
多设备间加密数据同步
分布式身份验证管理
技术架构图
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
手机设备 │ │ 平板设备 │ │ 手表设备 │
┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐ │
│ 生物认证 │─┼───▶│ │ 数据解密 │ │ │ │ 快速预览 │ │
└────────┘ │ │ └────────┘ │ │ └────────┘ │
└───────┬─────┘ └───────┬─────┘ └───────┬─────┘
│ │
└─────────┬────────┴─────────┬────────┘
│
┌───────▼───────┐ ┌───────▼───────┐
分布式数据服务 │ │ 加密安全服务 │
└───────────────┘ └───────────────┘
二、核心代码实现
生物认证服务封装
// BioAuthService.ets
import userIAM_userAuth from ‘@ohos.userIAM.userAuth’;
export class BioAuthService {
private authInstance: userIAM_userAuth.UserAuthInstance;
private readonly CHALLENGE = 123456; // 自定义挑战值
constructor() {
const config: userIAM_userAuth.AuthConfig = {
authType: [userIAM_userAuth.UserAuthType.FACE, userIAM_userAuth.UserAuthType.FINGERPRINT],
authTrustLevel: userIAM_userAuth.AuthTrustLevel.STRONG
};
this.authInstance = userIAM_userAuth.getAuthInstance(config);
async authenticate(): Promise<boolean> {
try {
const result = await this.authInstance.auth(this.CHALLENGE);
return result.result === userIAM_userAuth.AuthResultCode.SUCCESS;
catch (err) {
console.error('Authentication failed:', err);
return false;
}
async checkAuthSupport(): Promise<boolean> {
const types = await userIAM_userAuth.getAvailableAuthType();
return types.length > 0;
}
文件加密服务实现
// CryptoService.ets
import cryptoFramework from ‘@ohos.security.cryptoFramework’;
export class CryptoService {
private static readonly ALGORITHM = ‘AES256’;
private static readonly TRANSFORMATION = ‘AES256/GCM/PKCS5Padding’;
private static readonly IV_LENGTH = 12; // GCM推荐12字节IV
async encryptData(data: string, key: string): Promise<EncryptedData> {
try {
const cipher = await cryptoFramework.createCipher(this.TRANSFORMATION);
const secretKey = await this.generateSecretKey(key);
const iv = await this.generateIv();
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, secretKey, {
iv: iv,
authTag: true
});
const input = { data: data };
const output = await cipher.doFinal(input);
return {
cipherText: output.data,
iv: iv,
authTag: output.authTag
};
catch (err) {
console.error('Encryption failed:', err);
throw err;
}
private async generateSecretKey(password: string): Promise<cryptoFramework.SymKey> {
const generator = await cryptoFramework.createSymKeyGenerator(this.ALGORITHM);
const keyData = new Uint8Array(new TextEncoder().encode(password));
return generator.convertKey({ data: keyData });
private async generateIv(): Promise<Uint8Array> {
const iv = new Uint8Array(this.IV_LENGTH);
return cryptoFramework.getRandomValues(iv);
}
日记管理主页面
// DiaryMainPage.ets
@Entry
@Component
struct DiaryMainPage {
@State diaries: Array<Diary> = [];
@State isAuthenticated: boolean = false;
private bioAuth = new BioAuthService();
private crypto = new CryptoService();
private syncService = new DiarySyncService();
aboutToAppear() {
this.checkAuth();
build() {
Column() {
if (this.isAuthenticated) {
DiaryListView({
diaries: this.diaries,
onAdd: this.addDiary.bind(this),
onOpen: this.openDiary.bind(this)
})
else {
AuthPrompt({
onAuthRequest: this.authenticate.bind(this)
})
}
private async authenticate() {
const success = await this.bioAuth.authenticate();
if (success) {
this.isAuthenticated = true;
this.loadDiaries();
}
private async loadDiaries() {
const encrypted = await DiaryStorage.loadAll();
this.diaries = await Promise.all(encrypted.map(async e => {
const decrypted = await this.crypto.decryptData(e.content, this.getEncryptionKey());
return { …e, content: decrypted };
}));
private getEncryptionKey(): string {
// 实际应用中应从安全存储获取
return 'user_secret_key';
}
三、分布式数据同步实现
加密数据同步服务
// DiarySyncService.ets
import distributedData from ‘@ohos.data.distributedData’;
export class DiarySyncService {
private kvStore: distributedData.KVStore;
private readonly STORE_ID = ‘diary_sync_store’;
async init() {
const kvManager = await distributedData.createKVManager({
bundleName: ‘com.example.diary’
});
this.kvStore = await kvManager.getKVStore(this.STORE_ID, {
createIfMissing: true,
encrypt: true,
autoSync: true,
kvStoreType: distributedData.KVStoreType.SINGLE_VERSION
});
async syncDiary(diary: Diary, crypto: CryptoService) {
try {
const encrypted = await crypto.encryptData(diary.content, this.getSyncKey());
const syncData = {
id: diary.id,
title: diary.title,
encryptedContent: encrypted.cipherText,
iv: encrypted.iv,
authTag: encrypted.authTag,
timestamp: diary.timestamp,
deviceId: deviceInfo.deviceId
};
await this.kvStore.put(diary_${diary.id}, JSON.stringify(syncData));
catch (err) {
console.error('Sync failed:', err);
}
subscribeDiaryChanges(callback: (diary: Diary) => void, crypto: CryptoService) {
this.kvStore.on(‘dataChange’, distributedData.SubscribeType.SUBSCRIBE_TYPE_ALL, async (changes) => {
for (const change of changes) {
if (change.key.startsWith(‘diary_’)) {
const data = JSON.parse(change.value);
if (data.deviceId !== deviceInfo.deviceId) {
const decrypted = await crypto.decryptData({
cipherText: data.encryptedContent,
iv: data.iv,
authTag: data.authTag
}, this.getSyncKey());
callback({
id: data.id,
title: data.title,
content: decrypted,
timestamp: data.timestamp
});
}
});
private getSyncKey(): string {
// 实际应用中应从安全存储获取
return 'shared_sync_key';
}
多设备认证管理
// DeviceAuthManager.ets
import deviceManager from ‘@ohos.distributedHardware.deviceManager’;
export class DeviceAuthManager {
private trustedDevices: Array<string> = [];
async init() {
const manager = await deviceManager.createDeviceManager(‘com.example.diary’);
manager.on(‘deviceStateChange’, this.handleDeviceChange.bind(this));
manager.startDeviceDiscovery([‘diary_sync’]);
async authorizeNewDevice(deviceId: string): Promise<boolean> {
try {
const authRequest = {
authType: 1, // PIN码认证
extraInfo: {}
};
await deviceManager.authenticateDevice(deviceId, authRequest);
this.trustedDevices.push(deviceId);
return true;
catch (err) {
console.error('Device auth failed:', err);
return false;
}
isDeviceTrusted(deviceId: string): boolean {
return this.trustedDevices.includes(deviceId);
private handleDeviceChange(data: deviceManager.DeviceStateChangeData) {
if (data.action === 0 && !this.isDeviceTrusted(data.device.deviceId)) {
this.promptForAuthorization(data.device);
}
四、关键安全技术实现
密钥安全管理
// KeyManager.ets
import huks from ‘@ohos.security.huks’;
export class KeyManager {
private static readonly KEY_ALIAS = ‘diary_enc_key’;
private static readonly KEY_PARAMS: huks.HuksOptions = {
properties: [
tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
value: huks.HuksKeyAlg.HUKS_ALG_AES
},
tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256
},
tag: huks.HuksTag.HUKS_TAG_PURPOSE,
value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT |
huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT
},
tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
value: huks.HuksCipherMode.HUKS_MODE_GCM
]
};
async generateOrGetKey(): Promise<huks.HuksKey> {
try {
if (!await this.keyExists()) {
await huks.generateKey(this.KEY_ALIAS, this.KEY_PARAMS);
return await huks.importKey(this.KEY_ALIAS, this.KEY_PARAMS);
catch (err) {
console.error('Key operation failed:', err);
throw err;
}
private async keyExists(): Promise<boolean> {
try {
await huks.getKeyProperties(this.KEY_ALIAS);
return true;
catch {
return false;
}
安全存储实现
// SecureStorage.ets
import dataPreferences from ‘@ohos.data.preferences’;
export class SecureStorage {
private static readonly STORE_NAME = ‘diary_secure_store’;
private preferences: dataPreferences.Preferences;
async init() {
this.preferences = await dataPreferences.getPreferences(
getContext(this),
this.STORE_NAME
);
async put(key: string, value: string): Promise<void> {
await this.preferences.put(key, value);
await this.preferences.flush();
async get(key: string): Promise<string | undefined> {
return await this.preferences.get(key, '');
}
五、完整UI组件实现
生物认证提示组件
// AuthPrompt.ets
@Component
struct AuthPrompt {
@Prop onAuthRequest: () => void;
@State authTypes: Array<string> = [];
aboutToAppear() {
this.checkAvailableAuth();
build() {
Column() {
Image('secure_diary.png')
.width(120)
.height(120)
.margin({ bottom: 30 })
Text('请验证身份以访问日记')
.fontSize(20)
.margin({ bottom: 10 })
if (this.authTypes.length > 0) {
ForEach(this.authTypes, (type) => {
Button(使用${type}验证, { type: ButtonType.Capsule })
.width('80%')
.height(50)
.margin({ top: 10 })
.onClick(() => this.onAuthRequest())
})
else {
Text('未找到可用的生物认证方式')
.fontColor(Color.Gray)
}
private async checkAvailableAuth() {
const bioAuth = new BioAuthService();
if (await bioAuth.checkAuthSupport()) {
this.authTypes = ['人脸或指纹'];
}
日记列表组件
// DiaryListView.ets
@Component
struct DiaryListView {
@Prop diaries: Array<Diary>;
@Prop onAdd: () => void;
@Prop onOpen: (id: string) => void;
build() {
Column() {
// 添加按钮
Button(‘新建日记’, { type: ButtonType.Normal })
.width(‘90%’)
.margin(10)
.onClick(() => this.onAdd())
// 日记列表
List() {
ForEach(this.diaries, (diary) => {
ListItem() {
DiaryItem({
diary,
onClick: () => this.onOpen(diary.id)
})
})
.layoutWeight(1)
.divider({ strokeWidth: 1, color: '#F1F1F1' })
}
@Component
struct DiaryItem {
@Prop diary: Diary;
@Prop onClick: () => void;
build() {
Row() {
Column() {
Text(this.diary.title)
.fontSize(18)
Text(this.formatDate(this.diary.timestamp))
.fontSize(12)
.opacity(0.6)
.layoutWeight(1)
Image('arrow_right.png')
.width(20)
.height(20)
.padding(15)
.onClick(() => this.onClick())
}
六、项目部署与测试
权限配置
在module.json5中添加:
“requestPermissions”: [
“name”: “ohos.permission.ACCESS_BIOMETRIC”
},
“name”: “ohos.permission.USE_BIOMETRIC_INTERNAL”
},
“name”: “ohos.permission.DISTRIBUTED_DATASYNC”
},
“name”: “ohos.permission.ACCESS_USER_AUTH_INTERNAL”
]
测试方案
// 生物认证测试
describe(‘BioAuth’, () => {
it(‘should authenticate with valid credentials’, async () => {
const bioAuth = new BioAuthService();
const mockResult = { result: userIAM_userAuth.AuthResultCode.SUCCESS };
jest.spyOn(bioAuth, ‘authenticate’).mockResolvedValue(mockResult);
const result = await bioAuth.authenticate();
expect(result).toBe(true);
});
});
// 加密测试
describe(‘Encryption’, () => {
it(‘should encrypt and decrypt data correctly’, async () => {
const crypto = new CryptoService();
const original = ‘这是我的秘密日记’;
const encrypted = await crypto.encryptData(original, 'test_key');
const decrypted = await crypto.decryptData(encrypted, 'test_key');
expect(decrypted).toEqual(original);
});
});
七、总结与扩展
本方案实现了:
基于生物认证的安全访问控制
端到端的日记内容加密保护
多设备间的安全数据同步
完整的密钥生命周期管理
扩展方向:
添加云备份与恢复功能
实现日记情感分析
开发时间轴视图
集成图片和语音日记
鸿蒙的安全框架为隐私敏感型应用开发提供了坚实基础,开发者可基于此项目构建更丰富的安全应用场景。
