Implementação Simplificada de Armazenamento Seguro no Keychain com Swift usando KeychainSwift

No desenvolvimento para os ecossistemas Apple (iOS, macOS, tvOS e watchOS), o armazenamento seguro de dados sensíveis como senhas, tokens de API e chaves de criptografia é fundamental. O KeychainSwift é uma biblioteca de código aberto que abstrai a complexidade da API nativa do Keychain, oferecendo uma interface limpa e intuitiva em Swift para gerenciar esses dados confidenciais.

Configuração Inicial

Existem múltiplas formas de integrar o KeychainSwift ao seu projeto.

Via Swift Package Manager

Este é o método recomendado. No Xcode, navegue até File > Add Packages e insira o URL do repositório: https://github.com/evgenyneu/keychain-swift.git. Selecione a versão desejada e adicione ao projeto.

Via CocoaPods

Adicione a seguinte linha ao seu Podfile:

pod 'KeychainSwift', '~> 24.0'

Execute pod install no terminal.

Via Carthage

Inclua no seu Cartfile:

github "evgenyneu/keychain-swift" ~> 24.0'

Execute carthage update.

Utilização Básica

Instancie KeychainSwift para realizar operações CRUD.

Salvnado e Recuperando uma String

Ideal para dados de texto como senhas e tokens.

let meuArmazenamento = KeychainSwift()
meuArmazenamento.salvar("SenhaForte123", paraChave: "credencial_usuario")
let minhaSenha = meuArmazenamento.recuperarString(paraChave: "credencial_usuario")

Salvando e Recuperando um Booleano

Útil para armazenar preferências de estado do usuário.

let prefsSeguranca = KeychainSwift()
prefsSeguranca.salvar(true, paraChave: "autenticacao_biométrica")
let biometriaAtiva = prefsSeguranca.recuperarBool(paraChave: "autenticacao_biométrica")

Salvando e Recuperando Dados Binários

Para objetos complexos, serialize-os para Data primeiro.

let armazenamento = KeychainSwift()
let dadosPerfil = try JSONEncoder().encode(perfilUsuario)
armazenamento.salvar(dadosPerfil, paraChave: "perfil_serializado")
let dadosRecuperados = armazenamento.recuperarDados(paraChave: "perfil_serializado")

Gerenciamento de Itens

Para excluir um item específico:

armazenamento.apagar(paraChave: "minhaChave")

Para limpar todos os itens do Keychain da aplicação (não disponível em macOS):

armazenamento.limparTudo()

Configurações Avançadas de Segurança

Definindo o Nível de Acesso

O parâmetro comAcesso controla quando os dados podem ser acessados. O padrão .acessivelQuandoDesbloqueado oferece alta segurança. Para acesso em segundo plano, .acessivelAposPrimeiroDesbloqueio é menos restritivo.

armazenamento.salvar("SegredoTotal", paraChave: "dado_confidencial",
                    comAcesso: .acessivelQuandoDesbloqueado)

Sincronização entre Dispositivos via iCloud

Habilite a sincronização para compartilhar dados entre dispositivos do mesmo usuário com o iCloud Keychain ativado.

// No dispositivo A
let syncArmazenamento = KeychainSwift()
syncArmazenamento.sincronizavel = true
syncArmazenamento.salvar("DadoSincronizado", paraChave: "chave_compartilhada")

// No dispositivo B
let outroDispositivo = KeychainSwift()
outroDispositivo.sincronizavel = true
let dadoSync = outroDispositivo.recuperarString(paraChave: "chave_compartilhada")

Compartilhamento entre Aplicativos

Para compartilhar itens entre apps no mesmo dispositivo, configure um grupo de Keychain nas Capacidades do projeto (Keychain Sharing).

let compartilhado = KeychainSwift()
compartilhado.grupoAcesso = "SEU_TEAM_ID.com.seuapp.GrupoKeychain"
compartilhado.salvar("DadoParaAppParceiro", paraChave: "dado_compartilhado")

Tratamento de Erros e Depuração

Verifique o sucesso das operações analisando o retorno das funções salvar, apagar e limparTudo.

if !armazenamento.salvar("teste", paraChave: "chave_teste") {
    print("Falha ao salvar. Código de erro: \(armazenamento.ultimoCodigoResultado)")
}

O atributo ultimoCodigoResultado fornece detalhes específicos sobre o último erro ocorrido.

Estrutura do Projeto e Recursos

O código fonte está organizado de forma clara:

  • Sources/: Código principle (KeychainSwift.swift, opções de acesso, constantes).
  • Tests/: Suite completa de testes unitários.
  • Demo/: Aplicativo de exemplo para iOS.

A biblioteca é compatível com Swift 5.0+ e suporta iOS 7.0+, macOS 10.9+, tvOS 9.0+ e watchOS 2.0+.

Soluções para Problemas Comuns

Valor nil Inesperado: Um problema intermitente pode ocorrer, possivelmente relacionado a restrições de acesso. Verifique as configurações de acesso, o espaço disponível no Keychain e considere implementar uma lógica de repetição.

Isolamento em Testes Unitários: Use um prefixo de chave durante a inicialização para evitar poluição dos dados de produção.

let testeStorage = KeychainSwift(prefixoChave: "teste_unit_")
testeStorage.salvar("valor_teste", paraChave: "dado_experimento")
// A chave real no Keychain será "teste_unit_dado_experimento"

Obtenção de Referência: Para cenários como configuração de VPN (NEVPNProtocol), onde uma referência ao dado é necessária, use comoReferencia: true.

let refArmazenamento = KeychainSwift()
refArmazenamento.salvar(configVPN, paraChave: "vpn_config")
let referência = refArmazenamento.recuperarDados(paraChave: "vpn_config", comoReferencia: true)

Adotar a biblioteca KeychainSwift simplifica drasticamente o código relacionado à segurança de dados, permitindo que os desenvolvedores foquem na lógica de negócios da aplicação.

Tags: swift Keychain iOS Development macOS Development KeychainSwift

Publicado em 6-18 06:05