Harmony学习之安全与隐私保护
Harmony学习之安全与隐私保护
一、场景引入
小明开发的新闻阅读应用需要处理用户数据,包括个人信息、阅读记录、收藏内容等。如何确保这些数据的安全性和用户隐私,成为应用能否通过审核和获得用户信任的关键。HarmonyOS提供了完善的安全框架和隐私保护机制,帮助开发者构建安全可靠的应用。
二、核心安全概念
1. HarmonyOS安全架构
HarmonyOS采用分层的安全架构:
- 应用层安全:应用签名、权限管理、数据加密
- 框架层安全:访问控制、安全通信、密钥管理
- 系统层安全:安全启动、可信执行环境、安全存储
- 硬件层安全:安全芯片、硬件加密、生物识别
2. 主要安全威胁
- 数据泄露:敏感信息未加密存储或传输
- 权限滥用:应用获取不必要的权限
- 中间人攻击:网络传输被窃听或篡改
- 代码注入:恶意代码执行
- 逆向工程:应用被反编译分析
三、关键安全实践
1. 权限管理
权限申请与使用
// entry/src/main/ets/utils/PermissionManager.ets
import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
import common from '@ohos.app.ability.common';
export class PermissionManager {
private context: common.UIAbilityContext;
constructor(context: common.UIAbilityContext) {
this.context = context;
}
// 检查权限
async checkPermission(permission: string): Promise<boolean> {
try {
const atManager = abilityAccessCtrl.createAtManager();
const result = await atManager.checkAccessToken(
this.context.tokenId,
permission
);
return result === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
} catch (error) {
console.error('检查权限失败:', error);
return false;
}
}
// 请求权限
async requestPermission(permission: string): Promise<boolean> {
try {
const atManager = abilityAccessCtrl.createAtManager();
const result = await atManager.requestPermissionsFromUser(
this.context,
[permission]
);
return result.authResult[0] === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
} catch (error) {
console.error('请求权限失败:', error);
return false;
}
}
// 检查并请求权限
async checkAndRequestPermission(permission: string): Promise<boolean> {
const hasPermission = await this.checkPermission(permission);
if (hasPermission) {
return true;
}
return await this.requestPermission(permission);
}
// 获取权限列表
getPermissions(): string[] {
return [
'ohos.permission.INTERNET',
'ohos.permission.READ_MEDIA',
'ohos.permission.ACCESS_NETWORK_STATE',
'ohos.permission.READ_EXTERNAL_STORAGE',
'ohos.permission.WRITE_EXTERNAL_STORAGE'
];
}
// 检查所有必要权限
async checkAllRequiredPermissions(): Promise<boolean> {
const permissions = this.getPermissions();
for (const permission of permissions) {
const hasPermission = await this.checkPermission(permission);
if (!hasPermission) {
return false;
}
}
return true;
}
}
2. 数据加密存储
使用安全存储API
// entry/src/main/ets/utils/SecureStorage.ets
import cryptoFramework from '@ohos.security.cryptoFramework';
import dataPreferences from '@ohos.data.preferences';
export class SecureStorage {
private static instance: SecureStorage;
private preferences: dataPreferences.Preferences | null = null;
private keyAlias = 'my_app_key';
private constructor() {}
static getInstance(): SecureStorage {
if (!SecureStorage.instance) {
SecureStorage.instance = new SecureStorage();
}
return SecureStorage.instance;
}
// 初始化安全存储
async initialize(): Promise<void> {
try {
this.preferences = await dataPreferences.getPreferences(
globalThis.abilityContext,
'secure_data'
);
// 检查密钥是否存在
const hasKey = await this.checkKeyExists();
if (!hasKey) {
await this.generateKey();
}
} catch (error) {
console.error('初始化安全存储失败:', error);
throw error;
}
}
// 检查密钥是否存在
private async checkKeyExists(): Promise<boolean> {
try {
const keyGenerator = cryptoFramework.createSymKeyGenerator('AES256');
await keyGenerator.convertKey({ alias: this.keyAlias });
return true;
} catch (error) {
return false;
}
}
// 生成加密密钥
private async generateKey(): Promise<void> {
try {
const keyGenerator = cryptoFramework.createSymKeyGenerator('AES256');
const keyParams = {
algName: 'AES256',
keySpec: cryptoFramework.KeySpec.CRYPTO_ALGORITHM_AES,
keySize: 256
};
const key = await keyGenerator.generateSymKey(keyParams);
await keyGenerator.saveKey(key, this.keyAlias);
} catch (error) {
console.error('生成密钥失败:', error);
throw error;
}
}
// 加密数据
private async encryptData(data: string): Promise<string> {
try {
const keyGenerator = cryptoFramework.createSymKeyGenerator('AES256');
const key = await keyGenerator.convertKey({ alias: this.keyAlias });
const cipher = cryptoFramework.createCipher('AES256|GCM|PKCS7');
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, key, null);
const input = { data: new Uint8Array(data.split('').map(c => c.charCodeAt(0))) };
const encrypted = await cipher.doFinal(input);
return Array.from(encrypted.data).map(b => b.toString(16).padStart(2, '0')).join('');
} catch (error) {
console.error('加密数据失败:', error);
throw error;
}
}
// 解密数据
private async decryptData(encryptedData: string): Promise<string> {
try {
const keyGenerator = cryptoFramework.createSymKeyGenerator('AES256');
const key = await keyGenerator.convertKey({ alias: this.keyAlias });
const cipher = cryptoFramework.createCipher('AES256|GCM|PKCS7');
await cipher.init(cryptoFramework.CryptoMode.DECRYPT_MODE, key, null);
const dataArray = new Uint8Array(encryptedData.match(/.{1,2}/g)!.map(byte => parseInt(byte, 16)));
const input = { data: dataArray };
const decrypted = await cipher.doFinal(input);
return String.fromCharCode(...Array.from(decrypted.data));
} catch (error) {
console.error('解密数据失败:', error);
throw error;
}
}
// 存储加密数据
async putSecure(key: string, value: string): Promise<void> {
if (!this.preferences) {
throw new Error('安全存储未初始化');
}
try {
const encryptedValue = await this.encryptData(value);
await this.preferences.put(key, encryptedValue);
await this.preferences.flush();
} catch (error) {
console.error('存储加密数据失败:', error);
throw error;
}
}
// 获取解密数据
async getSecure(key: string, defaultValue: string = ''): Promise<string> {
if (!this.preferences) {
throw new Error('安全存储未初始化');
}
try {
const encryptedValue = await this.preferences.get(key, '');
if (!encryptedValue) {
return defaultValue;
}
return await this.decryptData(encryptedValue);
} catch (error) {
console.error('获取解密数据失败:', error);
return defaultValue;
}
}
// 删除加密数据
async deleteSecure(key: string): Promise<void> {
if (!this.preferences) {
throw new Error('安全存储未初始化');
}
try {
await this.preferences.delete(key);
await this.preferences.flush();
} catch (error) {
console.error('删除加密数据失败:', error);
throw error;
}
}
}
3. 网络安全通信
使用HTTPS和安全配置
// entry/src/main/ets/utils/SecureNetwork.ets
import http from '@ohos.net.http';
import ssl from '@ohos.net.ssl';
export class SecureNetwork {
private static instance: SecureNetwork;
private httpRequest: http.HttpRequest | null = null;
private constructor() {}
static getInstance(): SecureNetwork {
if (!SecureNetwork.instance) {
SecureNetwork.instance = new SecureNetwork();
}
return SecureNetwork.instance;
}
// 初始化安全网络配置
async initialize(): Promise<void> {
try {
// 配置SSL证书
const sslOptions: ssl.SSLConfig = {
trustedCerts: await this.loadTrustedCertificates(),
protocols: [ssl.Protocol.TLSV1_2, ssl.Protocol.TLSV1_3],
cipherSuites: [
'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384',
'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'
]
};
this.httpRequest = http.createHttp({
sslConfig: sslOptions
});
} catch (error) {
console.error('初始化安全网络失败:', error);
throw error;
}
}
// 加载信任证书
private async loadTrustedCertificates(): Promise<string[]> {
// 实际项目中应该从安全存储加载证书
return [
// 根证书列表
];
}
// 安全GET请求
async secureGet(url: string, headers?: Record<string, string>): Promise<any> {
if (!this.httpRequest) {
throw new Error('安全网络未初始化');
}
try {
const response = await this.httpRequest.request(url, {
method: http.RequestMethod.GET,
header: {
'Content-Type': 'application/json',
...headers
},
readTimeout: 10000,
connectTimeout: 5000
});
if (response.responseCode === 200) {
return JSON.parse(response.result.toString());
} else {
throw new Error(`请求失败: ${response.responseCode}`);
}
} catch (error) {
console.error('安全GET请求失败:', error);
throw error;
}
}
// 安全POST请求
async securePost(
url: string,
data: any,
headers?: Record<string, string>
): Promise<any> {
if (!this.httpRequest) {
throw new Error('安全网络未初始化');
}
try {
const response = await this.httpRequest.request(url, {
method: http.RequestMethod.POST,
header: {
'Content-Type': 'application/json',
...headers
},
extraData: JSON.stringify(data),
readTimeout: 10000,
connectTimeout: 5000
});
if (response.responseCode === 200) {
return JSON.parse(response.result.toString());
} else {
throw new Error(`请求失败: ${response.responseCode}`);
}
} catch (error) {
console.error('安全POST请求失败:', error);
throw error;
}
}
// 销毁网络连接
destroy() {
if (this.httpRequest) {
this.httpRequest.destroy();
this.httpRequest = null;
}
}
}
4. 隐私保护实践
用户数据保护
// entry/src/main/ets/utils/PrivacyManager.ets
import dataPreferences from '@ohos.data.preferences';
import cryptoFramework from '@ohos.security.cryptoFramework';
export class PrivacyManager {
private static instance: PrivacyManager;
private preferences: dataPreferences.Preferences | null = null;
private userConsentKey = 'user_consent';
private dataCollectionKey = 'data_collection_enabled';
private constructor() {}
static getInstance(): PrivacyManager {
if (!PrivacyManager.instance) {
PrivacyManager.instance = new PrivacyManager();
}
return PrivacyManager.instance;
}
// 初始化隐私管理
async initialize(): Promise<void> {
try {
this.preferences = await dataPreferences.getPreferences(
globalThis.abilityContext,
'privacy_settings'
);
} catch (error) {
console.error('初始化隐私管理失败:', error);
throw error;
}
}
// 检查用户是否同意隐私协议
async hasUserConsent(): Promise<boolean> {
if (!this.preferences) {
return false;
}
try {
return await this.preferences.get(this.userConsentKey, false);
} catch (error) {
console.error('检查用户同意失败:', error);
return false;
}
}
// 设置用户同意状态
async setUserConsent(consent: boolean): Promise<void> {
if (!this.preferences) {
throw new Error('隐私管理未初始化');
}
try {
await this.preferences.put(this.userConsentKey, consent);
await this.preferences.flush();
} catch (error) {
console.error('设置用户同意失败:', error);
throw error;
}
}
// 检查数据收集是否启用
async isDataCollectionEnabled(): Promise<boolean> {
if (!this.preferences) {
return false;
}
try {
return await this.preferences.get(this.dataCollectionKey, false);
} catch (error) {
console.error('检查数据收集状态失败:', error);
return false;
}
}
// 设置数据收集状态
async setDataCollectionEnabled(enabled: boolean): Promise<void> {
if (!this.preferences) {
throw new Error('隐私管理未初始化');
}
try {
await this.preferences.put(this.dataCollectionKey, enabled);
await this.preferences.flush();
} catch (error) {
console.error('设置数据收集状态失败:', error);
throw error;
}
}
// 匿名化用户数据
anonymizeUserData(data: any): any {
const anonymized = { ...data };
// 移除个人身份信息
delete anonymized.userId;
delete anonymized.name;
delete anonymized.email;
delete anonymized.phone;
delete anonymized.deviceId;
// 添加匿名标识符
anonymized.anonymousId = this.generateAnonymousId();
return anonymized;
}
// 生成匿名标识符
private generateAnonymousId(): string {
const timestamp = Date.now().toString();
const random = Math.random().toString(36).substring(2, 15);
return cryptoFramework.createHash('SHA256').update(timestamp + random).digest('hex');
}
// 清除用户数据
async clearUserData(): Promise<void> {
if (!this.preferences) {
throw new Error('隐私管理未初始化');
}
try {
await this.preferences.clear();
await this.preferences.flush();
} catch (error) {
console.error('清除用户数据失败:', error);
throw error;
}
}
}
四、实战案例:安全新闻阅读应用
1. 安全初始化
// entry/src/main/ets/entryability/EntryAbility.ets
import { SecureStorage } from '../utils/SecureStorage';
import { SecureNetwork } from '../utils/SecureNetwork';
import { PrivacyManager } from '../utils/PrivacyManager';
export default class EntryAbility extends Ability {
async onCreate(want, launchParam) {
console.log('EntryAbility onCreate');
try {
// 初始化安全存储
await SecureStorage.getInstance().initialize();
// 初始化安全网络
await SecureNetwork.getInstance().initialize();
// 初始化隐私管理
await PrivacyManager.getInstance().initialize();
console.log('安全组件初始化完成');
} catch (error) {
console.error('安全组件初始化失败:', error);
}
}
onDestroy() {
console.log('EntryAbility onDestroy');
// 销毁网络连接
SecureNetwork.getInstance().destroy();
}
}
2. 隐私协议页面
// entry/src/main/ets/pages/PrivacyAgreementPage.ets
@Component
struct PrivacyAgreementPage {
@State agreed: boolean = false;
async onAgree() {
try {
// 设置用户同意状态
await PrivacyManager.getInstance().setUserConsent(true);
// 跳转到主页面
router.replaceUrl({ url: 'pages/HomePage' });
} catch (error) {
console.error('设置用户同意失败:', error);
}
}
build() {
Column() {
Scroll() {
Column() {
Text('隐私协议')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 20 })
Text('我们非常重视您的隐私保护。本隐私协议说明了我们如何收集、使用、存储和保护您的个人信息。')
.fontSize(16)
.margin({ bottom: 15 })
// 隐私协议内容...
Row() {
Checkbox()
.selected(this.agreed)
.onChange((value) => {
this.agreed = value;
})
Text('我已阅读并同意隐私协议')
.fontSize(16)
.margin({ left: 10 })
}
.margin({ top: 20 })
Button('同意并继续')
.width('80%')
.height(50)
.backgroundColor('#007DFF')
.fontColor('#FFFFFF')
.onClick(() => this.onAgree())
.enabled(this.agreed)
.margin({ top: 20 })
}
.padding(20)
}
}
}
}
五、最佳实践
1. 安全配置
// module.json5
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET",
"reason": "用于网络请求",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.ACCESS_NETWORK_STATE",
"reason": "用于检查网络状态",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
],
"metadata": [
{
"name": "ohos.system.encryption",
"value": "true"
},
{
"name": "ohos.system.security_level",
"value": "high"
}
]
}
}
2. 安全审计
定期进行安全审计:
- 检查权限使用是否合理
- 验证数据加密是否有效
- 测试网络传输安全性
- 检查代码是否存在安全漏洞
六、总结
安全与隐私保护是应用开发中不可忽视的重要环节。通过合理使用HarmonyOS提供的安全框架,开发者可以:
- 保护用户数据:使用加密存储和安全传输
- 控制权限访问:最小权限原则
- 遵守隐私法规:获取用户同意,透明化数据使用
- 防范安全威胁:防止数据泄露和恶意攻击
建议开发者在应用上线前进行全面的安全测试,确保应用符合安全标准,保护用户权益。

浙公网安备 33010602011771号