Descrevemos um serviço de nuvem que usa hardware protegido para armazenar chaves criptográficas de forma a proteger o acesso a elas com um fator de conhecimento de entropia baixo (por exemplo, um PIN de desbloqueio de tela). O hardware protegido foi desenvolvido para evitar ataques de força bruta, o que é feito tornando as chaves criptográficas armazenadas irrecuperáveis após muitas tentativas erradas de inserir o fator de conhecimento correto.
Autor: Shabsi Walfish
Data da versão: 06/03/2018
Observação: este documento é um trabalho em andamento e os detalhes da implementação ainda estão sendo finalizados. Com a estabilização do sistema e mais documentação produzida, atualizaremos este artigo com mais detalhes (principalmente junto com versões de código aberto relevantes).
Visão geral
Normalmente, a criptografia (usada para garantir a privacidade dos dados) exige o uso de senhas que tenham alta entropia do ponto de vista do invasor. A alta entropia é exigida porque o esquema de criptografia precisa resistir a ataques de força bruta que exploram a área de todas as senhas prováveis até encontrar a correta. Com a disponibilidade do poder computacional de hoje, uma entropia mínima razoável para senhas criptográficas deve estar na casa de 70 ou 80 bits. Infelizmente, é muito difícil para os humanos memorizar e lembrar senhas consistentemente com essa quantidade de entropia1, principalmente se forem usadas raramente (mas o uso frequente de senhas de alta entropia é difícil e inconveniente). E isso gera um problema desafiador: como proteger dados privados com tecnologia de criptografia se queremos que a senha seja um "fator de conhecimento" fácil de lembrar para o usuário? Por diversos motivos, esse problema é tão difícil de resolver que os serviços de armazenamento do Cloud normalmente só criptografam dados com senhas gerenciadas pelo próprio provedor de armazenamento, em vez de se basear na capacidade do usuário de lembrar a própria senha.
Uma abordagem para equilibrar esse problema entre os requisitos das senhas criptográficas e das senhas que humanos conseguem lembrar é usar o serviço Cloud Key Vault (CKV) para armazenar uma "chave de recuperação" de alta entropia, protegida por uma senha de baixa entropia que pessoas consigam lembrar. O serviço CKV só libera a senha de recuperação a alguém que prove que sabe qual é a senha de baixa entropia da pessoa. O serviço CKV pode frustrar os ataques de força bruta contra a senha lembrável por humanos aplicando um limite absoluto para o número de tentativas de provar conhecimento dela. A própria chave de recuperação é uma chave criptográfica simétrica padrão, indicada para uso com um esquema de criptografia (autenticado) que possa, sem maiores problemas, criptografar um grande volume de dados (como um backup de disco) que possam ser armazenados com segurança em qualquer lugar – esses dados criptografados são inúteis a alguém que não tenha acesso à chave de recuperação.
Neste artigo, descrevemos a nossa abordagem para criar o serviço Cloud Key Vault usando módulos de hardware confiáveis (THMs). Nossa primeira implementação do CKV foi criada para proteger chaves de recuperação com o fator de conhecimento da tela de bloqueio (LSKF) do usuário – o PIN, senha ou o padrão usado para desbloquear smartphones. As pessoas conseguem lembrar o LSKF com facilidade. Ao mesmo tempo, essas senhas LSKF normalmente têm a quantidade certa de entropia para resistir a um invasor que tem pouquíssimas tentativas, o que as faz funcionar muito bem com o serviço CKV.
A primeira aplicação do nosso serviço Cloud Key Vault será permitir backups do Android criptografados no lado do cliente. Antes, os arquivos criptografados localmente em um dispositivo Android usavam uma chave protegida com o fator de conhecimento da tela de bloqueio do usuário, mas os backups desses arquivos armazenados (e criptografados) no Cloud não eram protegidos pela tela de bloqueio. Pela primeira vez, o Cloud Key Vault lança a proteção de tela de bloqueio para backups do Android armazenados também no Cloud. Isso significa que os servidores do Google não têm a capacidade de acessar ou restaurar o conteúdo dos backups criptografados – apenas um dispositivo com o LSKF do usuário pode descriptografar os backups.
Conceitos centrais
Inicialmente, a única plataforma de cliente suportada pelo serviço Cloud Key Vault será o próximo sistema operacional, o Android P, e, quando mencionamos o cliente neste artigo, estamos falando de um dispositivo que executa o Android P com os Serviços do Google Mobile. Nossa implementação ocorre em servidores Google especialmente designados que têm um chip Titan extra2 instalado. O chip Titan, que o Google desenvolveu, atua como um componente de hardware do nosso módulo de hardware confiável, e nós o fornecemos especialmente com um carregador de inicialização personalizado e um firmware que implementa nossos protocolos e mecanismos de garantia de segurança (como descrito aqui). Usamos técnicas de atestação de hardware para obter garantias de que o nosso protocolo está realmente funcionando no hardware Titan.
O serviço CKV deve se dimensionar para gerenciar tráfego de bilhões3 de dispositivos Android sem perder uma quantidade significativa de dados do usuário devido a falhas de hardware (por exemplo, chips queimados) ou passar por períodos de ociosidade prolongados devido a manutenção do data center. Por esse motivo, os servidores com chips Titan são organizados em grupos e cada grupo é composto de diversos THMs independentes que contêm, cada um, uma cópia do mesmo material de chave. Determinado grupo será distribuído em data centers fisicamente distantes em áreas de manutenção diferentes para garantir que o sistema possa atender às metas de disponibilidade e confiabilidade. Quanto à escalonabilidade, os clientes serão divididos a diversos grupos diferentes para podermos ajustar a capacidade do serviço simplesmente adicionando mais servidores para aumentar o número de grupos disponíveis.
Agora estamos prontos para enumerar os principais componentes da arquitetura do Cloud Key Vault.
Componentes da arquitetura/glossário
Fator de conhecimento de tela de bloqueio (LSKF): Uma senha que pessoas conseguem memorizar, como um PIN curto, um padrão de deslizamento em uma grade de 3 x 3 ou uma senha. Essa senha é usada para proteger localmente o recurso de bloqueio do dispositivo e é considerada um fator de autenticação primário (ou "forte") para o bloqueio de tela local do dispositivo do usuário.
Cliente: Um dispositivo do usuário final com o Android P como o sistema operacional e Serviços do Google Mobile ou outro software compatível.
-
Android Framework: usamos esse termo genérico para nos referir às APIs da próxima versão do sistema operacional Android (sucessor do Oreo, que ainda não tem nome definido até o momento da publicação deste conteúdo) ou posterior, mas nenhuma versão anterior é abrangida pelo termo.
Serviços do Google Mobile: Um conjunto de serviços e aplicativos que são executados no dispositivo do usuário final, permitindo que o dispositivo trabalhe com o sistema de contas do Google e as APIs de servidor personalizadas.
Agente de recuperação: Um aplicativo do sistema executado como parte do Google Play Services no espaço do usuário em um dispositivo Android P (ou similar). O agente de recuperação é responsável por executar vários protocolos no Cliente e estabelecer a interface com o sistema operacional Android, conforme a necessidade, para criar mensagens de protocolo que envolvam o LSKF.
Solicitação de recuperação: Quando o usuário quer recuperar a chave de recuperação, é preciso criar uma solicitação de recuperação, que tem uma cópia criptografada do LSKF que o usuário alega saber. Normalmente, o usuário tem que inserir o LSKF do dispositivo antigo no novo dispositivo que está tentando acessar a chave de recuperação do antigo.
Chave de recuperação: Uma senha criptográfica protegida pelo Cloud Key Vault usada para criptografar (e autenticar) dados no dispositivo do Cliente. Quando a chave de recuperação é colocada em um cofre (Vault), como demonstrado abaixo, a cópia local pode ser excluída assim que o Cliente terminar de usá-la para criptografar dados.
Serviço Cloud Key Vault (CKV): Um serviço de internet que permite aos dispositivos do Cliente armazenar chaves criptográficas protegidas por um LSKF lembrável por humanos.
-
Grupo: Um conjunto de servidores/THMs do cofre que podem atuar como réplicas redundantes de si mesmos.
Chave pública do grupo: A chave pública de um par de chaves gerada por um grupo de THMs específico. A chave privada correspondente só está disponível dentro dos THMs que estavam no grupo no momento da geração da chave.
Módulo de hardware confiável (THM): Um módulo de segurança dedicado (microcontrolador) desenvolvido para criar um ambiente computacional mínimo e confiável. No mínimo, o elemento protegido deve poder gerar e/ou armazenar chaves secretas e manter certo estado "mutável" não volátil (de forma que possa evitar ataques que envolvam retornar a um estado anterior).
Cofre: Uma entrada específica do banco de dados do serviço CKV, contendo uma única chave de recuperação protegida por LSKF do dispositivo. Um usuário final pode ter diversos Cofres no arquivo, com cada um deles correspondendo a um dispositivo ou LSKF diferente. Apenas o THM dentro de um servidor de cofre pode analisar ou extrair o conteúdo de um cofre.
Servidor de cofre: Uma máquina de finalidade geral que opera em um data center do Google e que foi retroajustada especialmente para adicionar um módulo de hardware confiável (THM).
Criação de protocolos
O protocolo CKV é composto de diversas fases. São elas:
Inicialização
Para inicializar o sistema, o Google disponibilizará uma chave pública de uma "raiz de confiança" que o Android Framework usará para verificar os atestados de hardware do Google. A chave de assinatura dessa raiz de confiança é armazenada off-line e cuidadosamente protegida, de forma a exigir a participação de diversos funcionários para assinar com ela. A chave pública dessa raiz de confiança faz parte do Android OS e só pode ser alterada por meio de uma atualização do SO.
O Google ainda publica uma lista de chaves públicas periodicamente para cada grupo de THM junto com um atestado na lista. O atestado da lista usa uma assinatura que está vinculada à raiz de confiança. Cada atualização da lista publicada também contém um número sequencial que possibilita impedir rollbacks. O agente de recuperação buscará a lista de chaves públicas de grupos publicada mais recentemente para fornecê-la ao Android Framework. A partir daí, o Android Framework verifica o atestado e seleciona uma chave pública de grupo da lista aleatoriamente para usar na fase de criação do cofre.
Criação de cofre (Vault)
Depois de ajudar o Framework a concluir a inicialização buscando a lista de chaves públicas de grupo, o agente de recuperação solicita a criação de um novo cofre ao Android Framework. Sempre que o LSKF é inserido pelo usuário em seguida, o Framework gera uma nova chave de recuperação e criptografa-a com uma chave derivada de um hash do LSKF e depois com a chave pública de grupo selecionada pelo Framework durante a fase de inicialização. O blob criptografado gerado é o cofre retornado pelo Framework ao agente de recuperação que, por sua vez, carrega-o no serviço CKV do Google.
Abertura de cofre (vault)
Quando o agente de recuperação do novo dispositivo precisa obter acesso à chave de recuperação armazenada em determinado cofre, primeiro ele solicita que o usuário insira o LSKF do dispositivo que criou o cofre originalmente. Em seguida, o agente de recuperação solicita ao Framework a criação de uma solicitação de recuperação usando esse LSKF. O Framework gera uma nova chave de solicitante e criptografa essa chave e o hash do LSKF solicitado com a mesma chave pública de grupo usada para criptografar o cofre. O blob criptografado gerado é chamado de solicitação de recuperação e o Framework a passa para o agente de recuperação que, por sua vez, apresenta-a ao serviço CKV.
O CKV encaminha a solicitação de recuperação (e seu cofre correspondente) aos servidores do cofre que fazem parte do grupo em questão. Em seguida, o THM dos servidores do cofre descriptografa a solicitação de recuperação e tenta extrair a chave de recuperação do cofre original usando o hash do LSKF solicitado (para derivar a chave de criptografia interna). Se o hash do LSKF original e o hash do LSKF solicitado forem iguais, o THM extrairá a chave de recuperação do cofre e a criptografará novamente com a chave de solicitante presente na solicitação de recuperação. Se não, o THM aumentará um contador de tentativas malsucedidas. Quando o contador atingir seu limite, o THM se recusará a processar todas as solicitações de recuperação seguintes deste cofre.
Por fim, se tudo ocorrer bem, a chave de recuperação recriptografada (que agora está criptografada sob a chave de solicitante) retornará do servidor do cofre diretamente para o Framework. O Framework usa sua cópia da chave de solicitante para descriptografar a chave de recuperação e, assim, o protocolo é concluído.
Medidas de segurança
O sistema do Cloud Key Vault busca fornecer "defesa profunda" com a inclusão de proteções de segurança em diversos níveis da pilha. Para dar uma ideia de como essas proteções funcionam, vamos começar descrevendo o Cliente e seguir todo o caminho da pilha até o Cloud Key Vault.
Segurança no cliente
Dependendo do OEM e do dispositivo, o fator de conhecimento da tela de bloqueio (LSKF) normalmente é armazenado e protegido no dispositivo usando diversos métodos, que variam de acordo com o fabricante. Por exemplo, os dispositivos Google Pixel 2 usam um módulo de segurança de hardware resistente a violações para armazenar a LSKF inativa e aplicar limites de velocidade para a validação do LSKF de acordo com o hardware. As novas Framework APIs que estão sendo lançadas para permitir o uso do Cloud Key Vault foram desenvolvidas para preservar as garantias de segurança atuais ao máximo, mesmo quando o dispositivo usa um módulo de segurança de hardware para proteger o armazenamento do LSKF.
Nosso foco aqui é nas proteções e nos problemas de segurança relevantes que afetam o novo recurso do Cloud Key Vault, e não em tentar fornecer uma explicação completa de todos os mecanismos de segurança associados ao LSKF.
Protegendo as Framework APIs
As novas Framework APIs adicionadas para oferecer suporte ao serviço CKV foram marcadas como @SystemApi e exigem permissões especiais, que garantem que só estejam disponíveis a aplicativos do sistema aprovados pelo OEM, como o Google Play Services. Com isso, conseguimos reduzir muito a superfície de ataque direta possivelmente exposta dos aplicativos que o usuário instala no dispositivo.
As Framework APIs também garantem que os cofres só sejam criados para chaves públicas de grupo que foram atestadas por uma raiz de confiança. A raiz de confiança é incorporada ao Framework pelo OEM quando é publicada e não pode ser alterada sem uma atualização do SO. Isso gera confiança de que o LSKF só está sendo usado para criar cofres que aplicarão proteções contra força bruta baseadas em hardware da forma correta. Ao usar THMs no Cloud Key Vault para a proteção contra força bruta do LSKF, podemos obter um nível de segurança comparável a usar hardware protegido no dispositivo para a mesma finalidade (como os dispositivos Google Pixel 2).
Como não presumimos que o LSKF será armazenado em algum lugar do dispositivo fora do hardware protegido, um novo cofre só poderá ser criado imediatamente após o desbloqueio do dispositivo. No momento em que o usuário digita o LSKF para desbloquear o dispositivo, o LSKF é disponibilizado brevemente ao Framework na RAM. É nesse momento que a nova API que cria o cofre o usa. Não é possível criar um novo cofre protegido por LSKF com o dispositivo bloqueado porque o LSKF não está disponível.
Protegendo o agente de recuperação
A proteção de segurança principal que disponibilizamos no agente de recuperação é que o protocolo foi desenvolvido para impedir o agente de recuperação de ver o LSKF do dispositivo atual e todas as chaves de recuperação. Apenas o Framework deve poder ver essas coisas no Cliente, o que dificulta muito a exploração de possíveis bugs ou vulnerabilidades de segurança no agente de recuperação. O agente de recuperação, na maioria das vezes, é usado para gerenciar eventos de ciclo de vida e o tráfego de dados entre o Cloud e o Framework. A única exceção a essa regra acontece durante uma recuperação imediatamente antes do protocolo de abertura do cofre, quando o usuário precisa inserir o LSKF do dispositivo antigo – a IU que coleta o LSKF solicitado do dispositivo antigo é implementada no agente de recuperação4. Porém, a implementação do agente de recuperação "esquece" o LSKF solicitado assim que o Framework assume a construção da solicitação de recuperação.
Recursos de segurança do protocolo
Embora uma análise completa do protocolo esteja além do escopo deste documento, queremos destacar algumas das proteções componentes do protocolo. Em especial, o protocolo só usa o hash do LSKF. Isso significa que, se o LSKF tiver alta entropia (por exemplo, se for uma boa senha de alta entropia), armazenar o cofre é muito melhor do que armazenar o hash de uma senha e, nesse caso, o hash da senha pode oferecer uma medida de segurança independente da segurança dos THMs. Por isso, oferecemos suporte a hash de limite de memória com sal do LSFK como parte do protocolo. Além disso, vinculamos o cofre criptograficamente a um identificador para o dispositivo que o criou e a solicitação de recuperação a um nonce usado como o desafio durante o protocolo de abertura de cofre para garantir que a solicitação de recuperação seja recente.
Como a chave de recuperação foi recentemente gerada nas criações de cofre, implementamos um rodízio de chaves substituindo um cofre atual por um recém-criado. O endereço do contador de tentativas malsucedidas usado pelo cofre é selecionado durante a fase de criação e o Android Framework garante que o endereço usado nos cofres seguintes não mude, a menos que o LSKF tenha sido alterado ou haja uma nova lista atestada de chaves públicas de grupo. Portanto, o rodízio da chave de recuperação pode ser feito sem prejudicar a proteção contra força bruta do LSKF.
Segurança do servidor para o Cloud Key Vault Service
O servidor é implementado usando uma combinação de software executado em hardware de servidor comum e firmware executado em hardware especializado (o chip Titan). Vamos descrever as proteções oferecidas em cada camada.
Proteções de hardware
A principal proteção de segurança implementada no servidor do serviço CKV são os módulos de hardware confiável (THMs), criados usando os chips Titan desenvolvidos exclusivamente pelo Google. Os chips executam firmware que expõe as APIs necessárias para implementar os protocolos do CKV. Em especial, eles podem gerar e compartilhar um par de chaves de forma segura com outros membros do grupo, com a lógica do firmware protegendo a chave privada contra vazamentos fora dos chips Titan do grupo. Eles também podem realizar a operação de abertura de cofre e manter um contador por cofre exclusivamente crescente de tentativas malsucedidas (nesse caso, o contador é apoiado pelo estado armazenado no chip Titan). Vamos disponibilizar uma descrição mais detalhada do protocolo executado pelo firmware do chip Titan do CKV em uma versão futura deste documento.
Considerando que a segurança do servidor advém da lógica do firmware dos chips Titan, precisamos garantir que a lógica não mude de forma que permita que os chips vazem senhas ou ignorem os limites do contador. Para tanto, alteramos também o carregador de inicialização do Titan para garantir que os dados armazenados do chip (como a chave privada do grupo) sejam excluídos permanentemente antes de uma atualização ser aplicada. O ponto negativo dessa proteção é que não podemos corrigir bugs no firmware sem sofrer perda de dados — em termos funcionais, atualizar o firmware é como destruir o hardware atual e substituí-lo por novos chips. Caso um patch crítico do firmware seja necessário, o Google precisará produzir e publicar uma lista totalmente nova de chaves públicas de grupo atestadas e migrar todos usuários para a nova lista gradualmente. Para reduzir esse risco, tentamos manter a base de código do firmware relativamente simples e auditá-la minuciosamente para buscar eventuais problemas de segurança.
Proteções de software
Além dos limites rígidos de falha por cofre impostos pelos THMs, o serviço CKJV também implementa limites de taxa baseados em software. A limitação de taxa visa a impedir que um invasor acesse a conta de um usuário e esgote rapidamente o limite de tentativas de recuperação malsucedidas, efetivamente bloqueando o acesso do usuário real às chaves de recuperação. Parecido com limites de tempo impostos pelo dispositivo do usuário após muitas tentativas malsucedidas de desbloquear a tela, o serviço CKV aplica um tempo cada vez maior para a nova tentativa após cada solicitação de abertura de cofre malsucedida seguinte.
Além disso, implementamos medidas de segurança padrão para serviços do Cloud que hospedam dados do usuário, incluindo controles de acesso, monitoramento e auditoria rigorosos.
Especificação detalhada do protocolo
A especificação detalhada do protocolo ainda está em desenvolvimento e este documento será atualizado para fornecer essas informações junto com a publicação do código do cliente no Android Open Source Project ainda este ano.
Observações
- "Towards Reliable Storage of 56-bit Secrets in Human Memory | USENIX." 1 de agosto de 2014, https://www.usenix.org/node/184458. ↩
- "Google Cloud Platform Blog: Titan em detalhes: a segurança do texto sem criptografia." 24 de agosto de 2017, https://cloudplatform.googleblog.com/2017/08/Titan-in-depth-security-in-plaintext.html. ↩
- "Google anuncia mais de 2 bilhões de dispositivos ativos mensalmente no Android..." 17 de maio de 2017, https://www.theverge.com/2017/5/17/15654454/android-reaches-2-billion-monthly-active-users. ↩
- Isso nos dá a chance de oferecer IUs flexíveis para inserir o LSKF de outro dispositivo — o Framework do dispositivo atual pode não ter uma IU adequada para a inserção do LSKF do dispositivo antigo. ↩