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提供的安全框架,开发者可以:

  1. 保护用户数据:使用加密存储和安全传输
  2. 控制权限访问:最小权限原则
  3. 遵守隐私法规:获取用户同意,透明化数据使用
  4. 防范安全威胁:防止数据泄露和恶意攻击

建议开发者在应用上线前进行全面的安全测试,确保应用符合安全标准,保护用户权益。

posted @ 2025-12-23 23:22  J_____P  阅读(0)  评论(0)    收藏  举报