segurança da informação ELDORADO

A segurança da informação está em voga. O advento da Indústria 4.0 põe as tecnologias de informação e comunicação em uma posição de importância e destaque que requer proteção na mesma medida. Ataques cibernéticos são cada vez mais comuns e automatizados, o que demanda cautela dos projetistas e desenvolvedores de hardware e software.

No escopo da mobilidade, os agentes responsáveis pela segurança são os fabricantes de celulares e os desenvolvedores de aplicações. A parte que cabe aos fabricantes vem sendo cumprida nos últimos anos, o que pode ser visto pela evolução, tanto dos componentes físicos usados nos aparelhos, quanto dos sistemas operacionais, que definem as APIs com que os aplicativos interagem. Este texto dá enfoque à outra ponta do ecossistema: os desenvolvedores de apps, especificamente do sistema Android.

Segurança em mente

Aplicar conceitos de segurança da informação no desenvolvimento de software é uma tarefa complexa. Uma das razões é que o objetivo não é atingido simplesmente ao se seguir uma metodologia ou rodar um programa de auditoria. O alvo dos ataques não é apenas o software criado, mas sim várias outras frentes, como as credenciais dos desenvolvedores, a infraestrutura em que o código é armazenado ou executado, ou os usuários do programa final. Nesse ponto, a segurança da informação se alinha à segurança das operações (OPSEC) nos objetivos a serem alcançados.

Uma análise qualitativa da segurança empenhada no código-fonte deve levar em conta o modelo de ameaça (threat model, em inglês) a que a aplicação estará sujeita. Para ilustrar, suponha que uma app armazene dados sensíveis do usuário. Que atores maliciosos poderão tentar obter essas informações lançando mão de qualquer meio? Por exemplo: outro app instalado no celular, outra pessoa em posse do aparelho, um malware infiltrado, um Estado nacional. Quais ameaças são factíveis e quais são os recursos necessários para impedi-las? As respostas para essas perguntas trarão as diretivas para o desenvolvimento seguro.

Um caso: como armazenar uma senha?

Uma senha de usuário é, por motivo óbvio, um dado sensível que oferece risco de ser usada maliciosamente caso não seja devidamente protegida. Antes de armazenar, a primeira questão a ser levantada é se a senha pode ser substituída por um identificador de sessão ou algo similar. Caso a arquitetura da aplicação em desenvolvimento permita a troca, o OAuth ou as APIs de credenciais do Android e do Google são meios mais seguros de autenticação que não envolvem lidar diretamente com senhas.

Caso seja necessário guardar a senha em armazenamento persistente, a documentação do Android sugere salvar um arquivo em armazenamento interno. É uma abordagem razoável, que impede o acesso simples por outras apps, mas uma aplicação com permissão root, se este for um risco a se considerar, é capaz de obter a informação facilmente.

Um meio de proteger ainda mais a senha ou qualquer informação sensível é criptografar os dados de interesse com uma chave protegida pelo sistema. Esse recurso do Android traz várias vantagens:

  • O uso da chave e a operação criptográfica é feita em um processo de sistema, portanto o conteúdo da chave não é repassado à aplicação do usuário;
  • A chave pode ser armazenada em hardware seguro dentro do celular, então mesmo que um atacante comprometa o sistema operacional e possa usar a chave, esta não pode ser extraída;
  • O uso da chave pode estar condicionado à autorização e à autenticação explícita do usuário, portanto, os dados criptografados podem estar protegidos mesmo com o aparelho em posse de outra pessoa.

Por meio dessa API é possível gerar e utilizar uma chave AES e criptografar uma senha ou, de modo mais abrangente, qualquer tipo de dado que se queira proteger com a cifra AES-GCM.

Segue código simplificado de exemplo para entendimento:

// Carrega keystore do Android, específico para cada aplicação.

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");

keyStore.load(null);




// Cria chave AES para encriptação e decriptação de cifra AES-GCM.

// A chave criada requer que o dispositivo esteja desbloqueado para efetuar a decriptação.

KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);

KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder("my_key",

       KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT);




builder.setBlockModes(KeyProperties.BLOCK_MODE_GCM);

builder.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE);




builder.setUnlockedDeviceRequired(true);




keyGenerator.init(builder.build());

Key key = keyGenerator.generateKey();




// Insere chave no keystore.

keyStore.setKeyEntry("my_key", key, null, null);




// Encripta uma senha com uso da cifra AES-GCM.

// Note que a cifra é capaz de encriptar qualquer sequência de bytes.

byte[] password;

int passwordLength;




Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

cipher.init(Cipher.ENCRYPT_MODE, keyStore.getKey("my_key", null));




// As três variáveis abaixo são necessárias para posterior decriptação.

byte[] encrypted;

int encryptedLength = cipher.doFinal(password, 0, passwordLength, encrypted, 0);

byte[] nonce = cipher.getIV();




// Decripta a senha cifrada por AES-GCM.

cipher = Cipher.getInstance("AES/GCM/NoPadding");

AlgorithmParameterSpec gcmSpec = new GCMParameterSpec(128, nonce);

cipher.init(Cipher.DECRYPT_MODE, keyStore.getKey("my_key", null), gcmSpec);




// Recupera a senha.

byte[] decrypted;

int decryptedLength = cipher.doFinal(encrypted, 0, encryptedLength, decrypted, 0);

Um projeto de aplicativo Android que exercita as APIs de chaves e cifras pode ser acessado no link: https://github.com/nandsito/android-example-aes-gcm

Uma ressalva: o uso de cifras criptográficas requer cuidado nos detalhes, pois um parâmetro equivocado ou um detalhe importante dos algoritmos que, porventura, é relevado, pode causar vazamento de informações sensíveis. Por exemplo, o reúso do vetor de inicialização, ou nonce, na cifra AES-GCM pode comprometer a confidencialidade da chave. Então é interessante que se conheça bem os algoritmos criptográficos usados.

Conclusão

A segurança da informação é um tema multidisciplinar e traz consigo a complexidade inerente de sua natureza. Isso foi ilustrado com a apresentação de tópicos relacionados – OPSEC, modelo de ameaça, criptografia – e a aplicação de todos esses conceitos no caso concreto do armazenamento de senhas. O fato de não haver uma solução única ou simples para a dada situação demonstra que a área de segurança tem potencial de pesquisa e inovação, principalmente para os problemas vindouros de tecnologias futuras.