Back to Blog
LGPD
2 de Janeiro de 202620 min de leituraby Sarah

LGPD e Segurança de Aplicativos Móveis: Guia Técnico Completo

Análise técnica aprofundada dos requisitos de segurança da LGPD para aplicativos móveis, incluindo criptografia, controles de acesso, gestão de incidentes e implementação prática com exemplos de código.

Introdução

A Lei Geral de Proteção de Dados (Lei nº 13.709/2018), em vigor desde setembro de 2020, estabelece um marco regulatório abrangente para o tratamento de dados pessoais no Brasil. Para desenvolvedores de aplicativos móveis, a conformidade com a LGPD não é apenas uma obrigação legal — é um diferencial competitivo em um mercado cada vez mais consciente sobre privacidade.

Este guia técnico aborda os aspectos práticos da implementação de controles de segurança exigidos pela LGPD em aplicativos Android e iOS, com foco especial nos Artigos 46 a 49 que tratam das medidas de segurança.

Fundamentos Legais

Quem Precisa se Adequar?

A LGPD aplica-se a qualquer operação de tratamento de dados pessoais realizada no território brasileiro, independentemente de onde a empresa esteja sediada. Isso inclui:

  1. Aplicativos que coletam dados de usuários brasileiros
  2. Empresas que oferecem serviços no Brasil
  3. Operações que visam oferecer bens ou serviços a indivíduos localizados no Brasil

| Elemento | Descrição | Exemplo em Apps | |----------|-----------|-----------------| | Dado Pessoal | Informação relacionada a pessoa identificada ou identificável | CPF, e-mail, localização GPS | | Dado Sensível | Dados sobre origem racial, convicção religiosa, saúde, biometria | Dados biométricos de autenticação | | Titular | Pessoa natural a quem os dados se referem | Usuário do aplicativo | | Controlador | Quem toma decisões sobre o tratamento | Desenvolvedor/empresa do app | | Operador | Quem realiza tratamento em nome do controlador | Provedor de cloud, SDK de analytics |

Bases Legais para Tratamento

Para tratar dados pessoais em seu aplicativo, você precisa fundamentar cada operação em uma das bases legais previstas no Art. 7º:

  • Consentimento: Manifestação livre, informada e inequívoca do titular
  • Execução de contrato: Necessário para prestação do serviço
  • Legítimo interesse: Quando atende interesses legítimos do controlador
  • Proteção do crédito: Para apps financeiros e de pagamentos

Requisitos Técnicos de Segurança

Art. 46 - Medidas de Segurança

O Artigo 46 da LGPD estabelece que agentes de tratamento devem adotar medidas de segurança técnicas e administrativas aptas a proteger os dados pessoais. Veja como implementar:

Criptografia em Repouso (Data at Rest)

Para dados armazenados localmente no dispositivo, utilize criptografia AES-256:

// Android: Criptografia usando EncryptedSharedPreferences
class ArmazenamentoSeguro(private val context: Context) {

    private val masterKey = MasterKey.Builder(context)
        .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
        .build()

    private val prefsSeguras = EncryptedSharedPreferences.create(
        context,
        "dados_usuario_lgpd",
        masterKey,
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )

    fun salvarDadoPessoal(chave: String, valor: String) {
        prefsSeguras.edit().putString(chave, valor).apply()
    }

    fun obterDadoPessoal(chave: String): String? {
        return prefsSeguras.getString(chave, null)
    }

    fun removerDadoPessoal(chave: String) {
        prefsSeguras.edit().remove(chave).apply()
    }
}
// iOS: Armazenamento seguro com Keychain
class ArmazenamentoSeguro {

    private let serviceName = "com.seuapp.dadospessoais"

    func salvar(dado: String, paraChave chave: String) throws {
        guard let dadosBytes = dado.data(using: .utf8) else {
            throw ErroArmazenamento.conversaoFalhou
        }

        let query: [String: Any] = [
            kSecClass as String: kSecClassGenericPassword,
            kSecAttrService as String: serviceName,
            kSecAttrAccount as String: chave,
            kSecValueData as String: dadosBytes,
            kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
        ]

        // Remove entrada existente se houver
        SecItemDelete(query as CFDictionary)

        let status = SecItemAdd(query as CFDictionary, nil)
        guard status == errSecSuccess else {
            throw ErroArmazenamento.falhaAoSalvar(status)
        }
    }

    func recuperar(chave: String) throws -> String? {
        let query: [String: Any] = [
            kSecClass as String: kSecClassGenericPassword,
            kSecAttrService as String: serviceName,
            kSecAttrAccount as String: chave,
            kSecReturnData as String: true,
            kSecMatchLimit as String: kSecMatchLimitOne
        ]

        var resultado: AnyObject?
        let status = SecItemCopyMatching(query as CFDictionary, &resultado)

        guard status == errSecSuccess,
              let dados = resultado as? Data,
              let valor = String(data: dados, encoding: .utf8) else {
            return nil
        }

        return valor
    }
}

Criptografia em Trânsito (Data in Transit)

A LGPD exige proteção de dados durante a transmissão. Implemente TLS 1.2+ com certificate pinning:

// Android: Configuração de segurança de rede
// res/xml/network_security_config.xml
/*
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="false">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>

    <domain-config>
        <domain includeSubdomains="true">api.seuapp.com.br</domain>
        <pin-set expiration="2026-12-31">
            <pin digest="SHA-256">SEU_HASH_BASE64_AQUI=</pin>
            <pin digest="SHA-256">HASH_BACKUP_AQUI=</pin>
        </pin-set>
    </domain-config>
</network-security-config>
*/

// Configuração do OkHttp com certificate pinning
val certificatePinner = CertificatePinner.Builder()
    .add("api.seuapp.com.br", "sha256/SEU_HASH_BASE64_AQUI=")
    .add("api.seuapp.com.br", "sha256/HASH_BACKUP_AQUI=")
    .build()

val clienteHttp = OkHttpClient.Builder()
    .certificatePinner(certificatePinner)
    .connectTimeout(30, TimeUnit.SECONDS)
    .build()

Art. 46, §2º - Privacidade desde a Concepção

O conceito de Privacy by Design deve ser incorporado desde o início do desenvolvimento:

Minimização de Dados

Colete apenas o estritamente necessário:

// INCORRETO - Coleta excessiva
data class UsuarioExcessivo(
    val nome: String,
    val cpf: String,
    val endereco: String,
    val telefone: String,
    val dataNascimento: String,
    val nomeMae: String,  // Necessário?
    val rendaMensal: String,  // Necessário?
    val estadoCivil: String  // Necessário?
)

// CORRETO - Apenas dados necessários para o serviço
data class UsuarioMinimo(
    val nome: String,
    val email: String,
    val telefone: String?  // Opcional, se realmente usado
)

Validação de Entrada

Implemente validação robusta para prevenir injeções e garantir integridade:

// iOS: Validação de dados de entrada
struct ValidadorDados {

    static func validarCPF(_ cpf: String) -> Bool {
        let numeros = cpf.replacingOccurrences(
            of: "[^0-9]",
            with: "",
            options: .regularExpression
        )

        guard numeros.count == 11 else { return false }

        // Verifica se não são todos iguais
        let conjunto = Set(numeros)
        guard conjunto.count > 1 else { return false }

        // Validação dos dígitos verificadores
        let digitos = numeros.compactMap { Int(String($0)) }

        func calcularDigito(base: [Int], pesos: [Int]) -> Int {
            let soma = zip(base, pesos).map { $0 * $1 }.reduce(0, +)
            let resto = soma % 11
            return resto < 2 ? 0 : 11 - resto
        }

        let primeiroDigito = calcularDigito(
            base: Array(digitos[0..<9]),
            pesos: [10, 9, 8, 7, 6, 5, 4, 3, 2]
        )

        let segundoDigito = calcularDigito(
            base: Array(digitos[0..<9]) + [primeiroDigito],
            pesos: [11, 10, 9, 8, 7, 6, 5, 4, 3, 2]
        )

        return digitos[9] == primeiroDigito && digitos[10] == segundoDigito
    }

    static func sanitizarEntrada(_ texto: String) -> String {
        // Remove caracteres potencialmente perigosos
        let caracteresProibidos = CharacterSet(charactersIn: "<>"';&")
        return texto.components(separatedBy: caracteresProibidos).joined()
    }
}

Art. 48 - Comunicação de Incidentes

A LGPD exige comunicação de incidentes de segurança à ANPD e aos titulares em prazo razoável. Implemente detecção e logging:

// Sistema de detecção e logging de incidentes
data class IncidenteSeguranca(
    val id: String = UUID.randomUUID().toString(),
    val timestamp: Long = System.currentTimeMillis(),
    val tipo: TipoIncidente,
    val severidade: Severidade,
    val descricao: String,
    val dadosAfetados: List<String>,
    val titularesAfetados: Int?,
    val acaoTomada: String?
)

enum class TipoIncidente {
    ACESSO_NAO_AUTORIZADO,
    VAZAMENTO_DADOS,
    PERDA_DADOS,
    ALTERACAO_INDEVIDA,
    TENTATIVA_INTRUSAO,
    DISPOSITIVO_COMPROMETIDO
}

enum class Severidade {
    BAIXA,
    MEDIA,
    ALTA,
    CRITICA
}

class GestorIncidentes(private val context: Context) {

    private val TAG = "IncidentesLGPD"

    fun registrarIncidente(incidente: IncidenteSeguranca) {
        // Log local seguro
        Log.e(TAG, "Incidente detectado: ${incidente.tipo}")

        // Enviar para backend (se conectado)
        enviarParaBackend(incidente)

        // Notificar equipe de segurança
        if (incidente.severidade == Severidade.CRITICA ||
            incidente.severidade == Severidade.ALTA) {
            notificarEquipeSeguranca(incidente)
        }
    }

    fun detectarDispositivoComprometido(): Boolean {
        return verificarRoot() || verificarEmulador() || verificarDebugger()
    }

    private fun verificarRoot(): Boolean {
        val indicadoresRoot = listOf(
            "/system/app/Superuser.apk",
            "/system/xbin/su",
            "/system/bin/su",
            "/data/local/xbin/su",
            "/data/local/bin/su"
        )

        return indicadoresRoot.any { File(it).exists() }
    }

    private fun verificarEmulador(): Boolean {
        return (Build.FINGERPRINT.contains("generic") ||
                Build.MODEL.contains("Emulator") ||
                Build.MANUFACTURER.contains("Genymotion"))
    }

    private fun verificarDebugger(): Boolean {
        return Debug.isDebuggerConnected()
    }
}

Art. 49 - Padrões de Boas Práticas

A LGPD menciona a adoção de padrões de boas práticas e governança. Para aplicativos móveis, isso inclui:

Controle de Acesso Baseado em Funções (RBAC)

// Implementação de controle de acesso
enum class NivelAcesso {
    TITULAR,      // Acesso apenas aos próprios dados
    ATENDENTE,    // Acesso a dados de clientes atendidos
    SUPERVISOR,   // Acesso a relatórios agregados
    ADMINISTRADOR // Acesso total (com auditoria)
}

class ControleAcesso(private val usuarioAtual: Usuario) {

    fun podeAcessarDados(titularId: String, operacao: Operacao): Boolean {
        return when (usuarioAtual.nivelAcesso) {
            NivelAcesso.TITULAR -> usuarioAtual.id == titularId
            NivelAcesso.ATENDENTE -> verificarRelacionamento(titularId)
            NivelAcesso.SUPERVISOR -> operacao == Operacao.LEITURA
            NivelAcesso.ADMINISTRADOR -> {
                registrarAcessoAdministrativo(titularId, operacao)
                true
            }
        }
    }

    private fun registrarAcessoAdministrativo(titularId: String, operacao: Operacao) {
        val auditoria = RegistroAuditoria(
            timestamp = System.currentTimeMillis(),
            usuarioId = usuarioAtual.id,
            titularId = titularId,
            operacao = operacao,
            justificativa = "Acesso administrativo"
        )
        LogAuditoria.registrar(auditoria)
    }
}

Timeout de Sessão

// iOS: Gerenciamento seguro de sessão
class GerenciadorSessao {

    private let tempoLimiteInatividade: TimeInterval = 300 // 5 minutos
    private var ultimaAtividade: Date = Date()
    private var timerVerificacao: Timer?

    func iniciarMonitoramento() {
        timerVerificacao = Timer.scheduledTimer(
            withTimeInterval: 30,
            repeats: true
        ) { [weak self] _ in
            self?.verificarSessao()
        }
    }

    func registrarAtividade() {
        ultimaAtividade = Date()
    }

    private func verificarSessao() {
        let tempoInativo = Date().timeIntervalSince(ultimaAtividade)

        if tempoInativo > tempoLimiteInatividade {
            encerrarSessao()
        }
    }

    private func encerrarSessao() {
        // Limpar dados sensíveis da memória
        limparDadosSensiveis()

        // Invalidar tokens
        TokenManager.shared.invalidar()

        // Redirecionar para tela de login
        NotificationCenter.default.post(
            name: .sessaoExpirada,
            object: nil
        )
    }

    private func limparDadosSensiveis() {
        // Sobrescrever variáveis com dados sensíveis
        // antes de liberar memória
    }
}

Direitos dos Titulares

O Art. 18 da LGPD garante direitos aos titulares que seu aplicativo deve suportar:

Implementação do Direito de Acesso (Art. 18, II)

// Endpoint para exportação de dados do titular
class ExportadorDados(private val repositorio: RepositorioDados) {

    fun exportarDadosTitular(titularId: String): RelatorioExportacao {
        val dadosPessoais = repositorio.obterTodosDados(titularId)
        val historico = repositorio.obterHistoricoTratamento(titularId)
        val consentimentos = repositorio.obterConsentimentos(titularId)

        return RelatorioExportacao(
            titular = titularId,
            dataGeracao = LocalDateTime.now(),
            dadosPessoais = dadosPessoais.map { mascarar(it) },
            categoriasColetadas = extrairCategorias(dadosPessoais),
            finalidades = extrairFinalidades(historico),
            compartilhamentos = obterCompartilhamentos(titularId),
            retencao = obterPoliticaRetencao(),
            consentimentos = consentimentos
        )
    }

    private fun mascarar(dado: DadoPessoal): DadoPessoalMascarado {
        // Mascara dados sensíveis mesmo na exportação
        return when (dado.tipo) {
            TipoDado.CPF -> dado.copy(valor = "${dado.valor.take(3)}.***.***-${dado.valor.takeLast(2)}")
            TipoDado.CARTAO -> dado.copy(valor = "**** **** **** ${dado.valor.takeLast(4)}")
            else -> dado.toMascarado()
        }
    }
}

Direito à Eliminação (Art. 18, VI)

// iOS: Implementação do direito à eliminação
class GestorEliminacao {

    func solicitarEliminacao(titularId: String, motivo: String) async throws {
        // 1. Verificar identidade do titular
        guard await verificarIdentidade(titularId) else {
            throw ErroLGPD.identidadeNaoConfirmada
        }

        // 2. Verificar se há base legal que exija retenção
        let obrigacoesRetencao = await verificarObrigacoesRetencao(titularId)

        if !obrigacoesRetencao.isEmpty {
            throw ErroLGPD.retencaoObrigatoria(obrigacoesRetencao)
        }

        // 3. Executar eliminação segura
        try await executarEliminacao(titularId)

        // 4. Propagar para operadores
        try await notificarOperadores(titularId)

        // 5. Registrar para auditoria
        registrarEliminacao(titularId: titularId, motivo: motivo)
    }

    private func executarEliminacao(_ titularId: String) async throws {
        // Eliminação segura com sobrescrita
        let arquivos = try await listarArquivosDoTitular(titularId)

        for arquivo in arquivos {
            try eliminarComSobrescrita(arquivo)
        }

        // Limpar de bancos de dados
        try await limparBancoDados(titularId)

        // Limpar de caches
        limparCaches(titularId)
    }

    private func eliminarComSobrescrita(_ url: URL) throws {
        let tamanho = try FileManager.default
            .attributesOfItem(atPath: url.path)[.size] as! UInt64

        // Sobrescrever 3 vezes com dados aleatórios
        for _ in 0..<3 {
            let dados = Data((0..<tamanho).map { _ in UInt8.random(in: 0...255) })
            try dados.write(to: url)
        }

        try FileManager.default.removeItem(at: url)
    }
}

Fiscalização da ANPD

A Autoridade Nacional de Proteção de Dados tem intensificado a fiscalização. Em 2024, a ANPD aplicou sanções superiores a R$ 50 milhões em multas.

Casos Recentes de Sanções

| Data | Empresa | Multa | Motivo | |------|---------|-------|--------| | Nov/2024 | Operadora de Telecom | R$ 14,4 milhões | Medidas de segurança inadequadas | | Out/2024 | Plataforma de E-commerce | R$ 7,2 milhões | Ausência de criptografia | | Set/2024 | App de Saúde | R$ 3,5 milhões | Vazamento via vulnerabilidade de API | | Ago/2024 | Fintech | R$ 9,8 milhões | Atraso na notificação de incidente |

O Que a ANPD Verifica

Durante fiscalizações, a ANPD costuma solicitar:

  1. Mapeamento de dados pessoais tratados
  2. Registro das operações de tratamento (Art. 37)
  3. Relatório de Impacto à Proteção de Dados (RIPD) quando aplicável
  4. Evidências de medidas de segurança implementadas
  5. Política de privacidade e termos de uso
  6. Registro de consentimentos obtidos
  7. Procedimentos de resposta a incidentes

Checklist de Conformidade para Apps Móveis

Controles Técnicos

  • [ ] Criptografia AES-256 para dados em repouso
  • [ ] TLS 1.2+ para todas as comunicações
  • [ ] Certificate pinning implementado
  • [ ] Armazenamento seguro (Keychain/Keystore)
  • [ ] Detecção de root/jailbreak
  • [ ] Timeout de sessão configurado
  • [ ] Logs não contêm dados pessoais
  • [ ] Dados sensíveis não em backups
  • [ ] Ofuscação de código aplicada
  • [ ] Validação de entrada implementada

Controles de Privacidade

  • [ ] Coleta minimizada ao necessário
  • [ ] Consentimento obtido de forma clara
  • [ ] Política de privacidade acessível
  • [ ] Mecanismo de revogação de consentimento
  • [ ] Exportação de dados do titular
  • [ ] Mecanismo de eliminação de dados
  • [ ] Notificação de alterações de política

Documentação

  • [ ] Registro de atividades de tratamento
  • [ ] Mapeamento de fluxo de dados
  • [ ] Relatório de Impacto (se aplicável)
  • [ ] Procedimento de resposta a incidentes
  • [ ] Contratos com operadores atualizados

Conclusão

A conformidade com a LGPD para aplicativos móveis requer uma abordagem holística que combine controles técnicos robustos, processos bem definidos e documentação adequada. Os requisitos de segurança dos Artigos 46 a 49 não são meras formalidades — são a espinha dorsal da proteção de dados pessoais dos seus usuários.

Pontos-chave a lembrar:

  1. A criptografia é essencial tanto em repouso quanto em trânsito
  2. Privacy by Design deve guiar todo o desenvolvimento
  3. Documentação é prova de conformidade
  4. Preparação para incidentes é obrigatória
  5. Direitos dos titulares devem ser tecnicamente suportados

A ANPD está cada vez mais ativa na fiscalização, e as multas são significativas. Mais importante ainda: a confiança dos usuários brasileiros em seu aplicativo depende da demonstração de compromisso real com a proteção de seus dados.


Verifique a conformidade do seu aplicativo com a LGPD. Inicie uma varredura agora.

Newsletter

Get the AppAudix Security Notes

A short mobile app security brief with PCI DSS, OWASP MASVS, Android, and iOS findings.

We verify email ownership before subscribing. No spam.

Share this article

Secure Your Mobile App Today

Automatically scan your Android or iOS app for security vulnerabilities and compliance issues.

Cookie preferences

We use necessary storage for security and login. With your permission, we also use analytics to understand page journeys and marketing pixels to measure ad campaigns.