O Android 7.0 é executado em um modo seguro de inicialização direta quando o dispositivo é ligado, mas o usuário não o desbloqueia. Para isso, o sistema oferece dois locais de armazenamento para dados:
- O armazenamento criptografado por credenciais, que é o local de armazenamento padrão e só é disponibilizado depois que o usuário desbloqueia o dispositivo.
- O armazenamento criptografado do dispositivo, que é um local de armazenamento disponibilizado durante o modo de inicialização direta e depois que o usuário desbloqueia o dispositivo.
Por padrão, os apps não são executados durante o modo de inicialização direta. Caso seu app precise executar ações nesse modo, você pode registrar os componentes que precisam ser executados. Alguns casos de uso comuns para apps que precisam ser executados no modo de inicialização direta incluem:
- Apps com notificações agendadas, como apps de despertador
- Apps que fornecem notificações importantes ao usuário, como apps de SMS
- Apps que fornecem serviços de acessibilidade, como o Talkback
Caso seu app precise acessar dados durante o modo de inicialização direta, use o armazenamento criptografado do dispositivo. Esse tipo de armazenamento contém dados criptografados com uma chave que só é disponibilizada depois que o dispositivo realiza uma inicialização verificada.
Para dados que precisam ser criptografados com uma chave associada a credenciais do usuário, como um PIN ou uma senha, use o armazenamento criptografado por credenciais. O armazenamento criptografado por credenciais fica disponível depois que o usuário desbloqueia o dispositivo e até que o usuário o reinicie. Se o usuário ativar a tela de bloqueio após o desbloqueio do dispositivo, o armazenamento criptografado por credenciais vai continuar disponível.
Solicitar acesso para executar durante a inicialização direta
Os apps precisam registrar os componentes no sistema antes de
poderem ser executados no modo de inicialização direta ou acessar o armazenamento criptografado do
dispositivo. Os apps são registrados no sistema marcando os componentes como tendo
reconhecimento de criptografia. Para marcar seu componente como tendo reconhecimento de criptografia, defina o
atributo android:directBootAware
como "true" no manifesto.
Componentes com reconhecimento de criptografia podem se registrar para receber uma
mensagem de transmissão ACTION_LOCKED_BOOT_COMPLETED
do sistema
quando o dispositivo é reiniciado. Nesse momento, o armazenamento criptografado
do dispositivo é disponibilizado e pode executar tarefas necessárias
durante o modo de inicialização, como o acionamento de um alarme programado.
O snippet de código abaixo é um exemplo de como registrar um
BroadcastReceiver
como tendo reconhecimento de criptografia e adicionar um
filtro de intent para ACTION_LOCKED_BOOT_COMPLETED
no manifesto do app:
<receiver android:directBootAware="true" > ... <intent-filter> <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" /> </intent-filter> </receiver>
Quando o usuário desbloqueia o dispositivo, todos os componentes podem acessar o armazenamento criptografado do dispositivo e também o armazenamento criptografado por credenciais.
Acessar o armazenamento criptografado do dispositivo
Para acessar o armazenamento criptografado do dispositivo, crie uma segunda
instância de Context
chamando
Context.createDeviceProtectedStorageContext()
. Todas as chamadas
da API de armazenamento que usam esse contexto acessam o armazenamento criptografado do dispositivo. O
exemplo abaixo acessa o armazenamento criptografado do dispositivo e abre um
arquivo de dados do app:
Kotlin
val directBootContext: Context = appContext.createDeviceProtectedStorageContext() // Access appDataFilename that lives in device encrypted storage val inStream: InputStream = directBootContext.openFileInput(appDataFilename) // Use inStream to read content...
Java
Context directBootContext = appContext.createDeviceProtectedStorageContext(); // Access appDataFilename that lives in device encrypted storage FileInputStream inStream = directBootContext.openFileInput(appDataFilename); // Use inStream to read content...
Use o armazenamento criptografado do dispositivo apenas para informações que precisam estar acessíveis durante o modo de inicialização direta. Não use esse tipo de armazenamento como um repositório criptografado para fins gerais. Para informações particulares do usuário ou para dados criptografados que não são necessários durante o modo de inicialização direta, use o armazenamento criptografado por credenciais.
Receber notificações quando o usuário desbloquear
Quando o usuário desbloqueia o dispositivo após a reinicialização, seu app pode voltar a acessar o armazenamento criptografado por credenciais e usar serviços normais do sistema que dependem das credenciais do usuário.
Para receber uma notificação quando o usuário desbloqueia o dispositivo depois de uma reinicialização,
registre um BroadcastReceiver
usando o componente
em execução para ouvir mensagens de notificação de desbloqueio. Quando o usuário desbloqueia o dispositivo
após a inicialização:
- Se o app tem processos em primeiro plano que precisem de notificação imediata,
ouça a mensagem
ACTION_USER_UNLOCKED
. - Se o app usa somente processos em segundo plano que possam agir com base em uma notificação atrasada,
ouça a
mensagem
ACTION_BOOT_COMPLETED
.
Se o usuário desbloquear o dispositivo, você pode detectar isso chamando
UserManager.isUserUnlocked()
.
Migrar dados atuais
Se o usuário atualizar o dispositivo para usar o modo de inicialização direta, você pode ter
dados que precisem ser migrados para o armazenamento criptografado do dispositivo. Use
Context.moveSharedPreferencesFrom()
e
Context.moveDatabaseFrom()
, com o contexto de destino como o autor da chamada do método e o contexto de origem como o argumento, para migrar dados de preferência e do banco de dados
entre o armazenamento criptografado por credenciais e o armazenamento criptografado do dispositivo.
Não migre informações particulares do usuário, como senhas ou tokens de autorização, do armazenamento criptografado por credenciais para o armazenamento criptografado do dispositivo. Tenha bom senso ao decidir quais outros dados migrar para o armazenamento criptografado do dispositivo. Em alguns casos, pode ser necessário gerenciar conjuntos separados de dados nos dois repositórios criptografados.
Testar o app com reconhecimento de criptografia
Teste seu app com reconhecimento de criptografia com o modo de inicialização direta ativado.
A maioria dos dispositivos com versões recentes do Android ativa o modo de inicialização direta sempre que uma credencial da tela de bloqueio (PIN, padrão ou senha) é definida. Isso se aplica especificamente a todos os dispositivos que usam a criptografia baseada em arquivos. Para verificar se um dispositivo usa criptografia baseada em arquivos, execute este comando shell:
adb shell getprop ro.crypto.type
Se a saída for file
, o dispositivo tem a criptografia baseada em arquivos
ativada.
Em dispositivos que não usam a criptografia baseada em arquivos por padrão, pode haver outras opções para testar o modo de inicialização direta:
-
Alguns dispositivos que usam criptografia de disco completo (
ro.crypto.type=block
) e executam o Android 7.0 ao 12 podem ser convertidos para criptografia baseada em arquivos. Há duas maneiras de fazer isso:- No dispositivo, ative as Opções do desenvolvedor, se ainda não estiverem ativadas. Para isso, acesse Configurações > Sobre o telefone e toque em Número da versão sete vezes. Em seguida, acesse Configurações > Opções do desenvolvedor e selecione Converter para criptografia de arquivos.
- Como alternativa, execute os seguintes comandos do shell:
adb reboot-bootloader
fastboot --wipe-and-use-fbe
Aviso: qualquer método de conversão para criptografia baseada em arquivos exclui permanentemente todos os dados do usuário no dispositivo.
-
Dispositivos com o Android 13 ou versões anteriores oferecem suporte a um modo de inicialização direta "emulado" que usa permissões de arquivo para simular os efeitos de arquivos criptografados sendo bloqueados e desbloqueados. Use o modo emulado apenas durante o desenvolvimento. Ele pode causar perda de dados. Para ativar o modo de inicialização direta emulado, defina um padrão de bloqueio no dispositivo. Caso seja solicitada uma tela de inicialização segura ao definir esse padrão, escolha "Não" e, em seguida, execute este comando shell:
adb shell sm set-emulate-fbe true
Para desativar o modo de inicialização direta emulado, execute este comando shell:
adb shell sm set-emulate-fbe false
Executar qualquer um desses comandos faz com que o dispositivo seja reiniciado.
Verificar o status de criptografia da política do dispositivo
Apps de administração de dispositivo podem usar
DevicePolicyManager.getStorageEncryptionStatus()
para verificar o status atual de criptografia do dispositivo.
Se o app for direcionado a um nível de API anterior ao Android 7.0 (API 24),
getStorageEncryptionStatus()
vai retornar
ENCRYPTION_STATUS_ACTIVE
se o dispositivo estiver usando criptografia de disco completo
ou baseada em arquivos com a inicialização direta. Em ambos os casos, os dados são
sempre armazenados criptografados em repouso.
Se o app for direcionado ao Android 7.0 (API 24) ou versões mais recentes,
getStorageEncryptionStatus()
vai retornar
ENCRYPTION_STATUS_ACTIVE
se o dispositivo estiver usando a criptografia de disco completo. O método vai retornar
ENCRYPTION_STATUS_ACTIVE_PER_USER
se o dispositivo estiver usando a criptografia baseada em arquivos
com inicialização direta.
Se você criar um app de administração de dispositivo
direcionado ao Android 7.0, verifique a presença de
ENCRYPTION_STATUS_ACTIVE
e
ENCRYPTION_STATUS_ACTIVE_PER_USER
para determinar se o dispositivo está
criptografado.
Outros exemplos de código
O exemplo DirectBoot (em inglês) demonstra com mais detalhes o uso das APIs abordadas nesta página.