Protegendo Dados Sensíveis no HarmonyOS: Gerenciamento Dinâmico de Permissões e Criptografia de Hardware

Arquitetura de Privacidade em Aplicações de Saúde no HarmonyOS

O desenvolvimento de aplicações que processam dados biométricos e de geolocalização exige uma arquitetura de segurança robusta. No ecossistema HarmonyOS, a proteção da privacidade do usuário é garantida através de mecanismos de controle de aceso granular, isolamento de dados em sandbox e criptografia em nível de hardware. A seguir, detalhamos a implementação prática desses conceitos utilizando o modelo Stage e a linguagem ArkTS em um aplicativo de monitoramento de atividades físicas.

Cenário de Aplicação e Requisitos de Segurança

O aplicativo neceessita acessar o sensor de movimento (ohos.permission.ACTIVITY_MOTION), serviços de geolocalização (ohos.permission.LOCATION) e persistir registros localmente. A arquitetura deve garantir que o usuário possa revogar acessos dinamicamente e que informações médicas sensíveis permaneçam ilegíveis para processos não autorizados, mesmo em caso de comprometimento do sistema de arquivos.

Declaração de Permissões no Modelo Stage

No modelo de desenvolvimento Stage do HarmonyOS, as permissões são declaradas no arquivo module.json5. A configuração abaixo demonstra a adesão ao princípio do menor privilégio, especificando o contexto exato de uso para cada permissão.

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.ACTIVITY_MOTION",
        "reason": "$string:reason_motion_tracking",
        "usedScene": {
          "abilities": ["EntryAbility"],
          "when": "inuse"
        }
      },
      {
        "name": "ohos.permission.LOCATION",
        "reason": "$string:reason_route_mapping",
        "usedScene": {
          "abilities": ["EntryAbility"],
          "when": "inuse"
        }
      }
    ]
  }
}

Solicitação Dinâmica e Tratamento de Acesso

A verificação e solicitação de permissões em tempo de execução são gerenciadas pelo abilityAccessCtrl. O código abaixo ilustra a checagem assíncrona do estado das permissões e o tratamento de recusas pelo usuário, desativando módulos específicos quando o acesso é negado.

import { abilityAccessCtrl, Permissions } from '@kit.AbilityKit';
import { common } from '@kit.AbilityKit';

async function solicitarPermissoesContextuais(context: common.UIAbilityContext): Promise<void> {
  const permissoesNecessarias: Array<Permissions> = [
    'ohos.permission.ACTIVITY_MOTION',
    'ohos.permission.LOCATION'
  ];

  const atmc = abilityAccessCtrl.createAtManager();
  const permissoesFaltantes: Array<Permissions> = [];

  for (const perm of permissoesNecessarias) {
    const status = await atmc.checkAccessToken(context.abilityInfo.bundleName, perm);
    if (status !== abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
      permissoesFaltantes.push(perm);
    }
  }

  if (permissoesFaltantes.length > 0) {
    const resultado = await context.requestPermissionsFromUser(permissoesFaltantes);
    resultado.permissions.forEach((perm, index) => {
      if (resultado.authResults[index] !== 0) {
        console.error(`Acesso negado para: ${perm}. Desativando módulo correspondente.`);
        desativarRecursoEspecifico(perm);
      }
    });
  }
}

function desativarRecursoEspecifico(permissao: string): void {
  if (permissao === 'ohos.permission.LOCATION') {
    // Lógica para ocultar componentes de mapa e parar serviços de rastreamento
  }
}

Criptografia de Dados Sensíveis com HUKS

Para proteger registros de saúde, utilizamos o Huawei Universal KeyStore (HUKS), que opera dentro do Trusted Execution Enviroment (TEE). Isso garante que as chaves criptográficas nunca sejam expostas ao sistema operacional principal. O exemplo abaixo demonstra a geração de uma chave AES-256 e a criptografia de um payload antes da persistência no sandbox da aplicação.

import { huks } from '@kit.SecurityKit';
import { fs } from '@kit.CoreFileKit';

const ALIAS_CHAVE_MESTRA = 'chave_saude_aes_256';

async function criptografarEPersistir(context: any, dadosTexto: string): Promise<void> {
  const caminhoArquivo = `${context.filesDir}/registros_saude_seguros.bin`;

  // Inicializa a chave no TEE se não existir
  if (!await huks.isKeyExist(ALIAS_CHAVE_MESTRA, {})) {
    const propriedades: huks.HuksOptions = {
      properties: new Array(
        { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_AES },
        { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: huks.HuksAESKeySize.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 },
        { tag: huks.HuksTag.HUKS_TAG_PADDING, value: huks.HuksKeyPadding.HUKS_PADDING_NONE }
      )
    };
    await huks.generateKey(ALIAS_CHAVE_MESTRA, propriedades);
  }

  // Executa a criptografia do payload
  const textoCodificado = new TextEncoder().encode(dadosTexto);
  const opcoesCriptografia: huks.HuksOptions = { properties: [] };
  const resultadoCripto = await huks.encrypt(ALIAS_CHAVE_MESTRA, opcoesCriptografia, textoCodificado);

  // Persiste o blob criptografado no diretório isolado da aplicação
  let arquivo = fs.openSync(caminhoArquivo, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  fs.writeSync(arquivo.fd, resultadoCripto.outData);
  fs.closeSync(arquivo);
}

Reavaliação de Permissões no Ciclo de Vida

No HarmonyOS, a revogação de permissões enquanto o aplicativo está em segundo plano deve ser tratada durante o retorno ao primeiro plano. A implementação do ciclo de vida da UIAbility garante que o estado de acesso seja reavaliado e que dados em cache sejam purgados imediatamente se o privilégio for removido pelo usuário nas configurações do sistema.

import { UIAbility } from '@kit.AbilityKit';

export class EntryAbility extends UIAbility {
  onForeground(): void {
    // Reavalia permissões críticas ao retornar para o primeiro plano
    this.reavaliarEstadoPermissoes();
  }

  private async reavaliarEstadoPermissoes(): Promise<void> {
    const atmc = abilityAccessCtrl.createAtManager();
    const statusLocalizacao = await atmc.checkAccessToken(
      this.context.abilityInfo.bundleName, 
      'ohos.permission.LOCATION'
    );
    
    if (statusLocalizacao !== abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
      this.purgarCacheGeolocalizacao();
    }
  }

  private purgarCacheGeolocalizacao(): void {
    // Limpeza imediata de dados de localização em memória e em disco
  }
}

Matriz de Comportamento do Sistema e da Aplicação

Ação do Usuário Comportamento do Sistema Resposta da Aplicação
Execução inicial do aplicativo Exibe diálogos de permissão contextuais e sequenciais Coleta apenas dados de movimento e inicializa o armazenamento
Navegação para o módulo de mapas Solicita acesso à geolocalização em tempo de uso Inicia o rastreamento de rotas e renderiza a interface
Revogação de permissão nas configurações do SO Sistema bloqueia chamadas subsequentes à API de localização Detecta mudança no ciclo de vida (onForeground) e purga o cache
Visualização de métricas de saúde históricas Nenhuma intervenção ou prompt do sistema Descriptografa o blob local via TEE e atualiza a interface do usuário

Análise de Complexidade Computacional

Complexidade de Tempo:

  • Verificação de Permissões: O(1) (Consulta direta e otimizada ao cache do Access Token Manager).
  • Criptografia de Dados: O(n) (Onde n é o tamanho do payload, utilizando AES-GCM com aceleração de hardware).

Complexidade de Espaço:

  • Gerenciamento de Chaves: O(1) (Tamanho fixo de 256 bits alocado de forma segura no Secure Element/TEE).
  • Buffer de Criptografia: O(n) (Alocação temporária em memória para o texto cifrado antes da operação de I/O em disco).

Tags: HarmonyOS ArkTS HUKS TEE ControleDeAcesso

Publicado em 6-22 20:28