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)(Ondené 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).