Armazenamento de Segredos no Keychain
Salve e recupere credenciais com segurança.
Armazenamento de Segredos no Keychain é uma aula grátis de Swift Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Swift Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Swift Academy inclui 4 aulas no total.
Por que usar as Chaves
Senhas, tokens e chaves nunca devem ficar em UserDefaults ou em arquivos simples — eles são fáceis de ler. O serviço de Chaves é um banco de dados criptografado e gerenciado pelo sistema para pequenos segredos, protegido pelo hardware e pelo código de acesso do usuário. É o único local correto para credenciais.
import Security
// Keychain stores secrets encrypted at rest,
// survives app updates, and gates access by policy.Os itens são dicionários
A API de Serviços de Chaves é baseada em C: você descreve um item com um dicionário de consulta [String: Any], usando chaves constantes kSec.... A mesma estrutura de dicionário é reutilizada para adicionar, pesquisar, atualizar e apagar.
import Security
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: "user@example.com",
kSecAttrService as String: "com.example.app"
]
_ = queryClasses de itens
A chave kSecClass escolhe o tipo de item. kSecClassGenericPassword abrange tokens e segredos do aplicativo; kSecClassInternetPassword armazena credenciais de servidores com atributos de host e protocolo. A maioria dos segredos de aplicativos usa uma senha genérica.
import Security
// kSecClassGenericPassword -> tokens, API keys
// kSecClassInternetPassword -> server logins
// kSecClassKey / Certificate -> crypto material
let cls = kSecClassGenericPassword
_ = clsAdicionando um item
SecItemAdd insere um novo item. Você inclui os dados em kSecValueData como Data, além de atributos que o identificam. Ele retorna um OSStatus — errSecSuccess significa que a operação funcionou.
import Security
func save(_ token: String, account: String) -> Bool {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account,
kSecValueData as String: Data(token.utf8)
]
return SecItemAdd(query as CFDictionary, nil)
== errSecSuccess
}Lidando com duplicatas
Adicionar um item cujos atributos de identificação já existem retorna errSecDuplicateItem. Um salvamento robusto tenta usar SecItemAdd e, em caso de duplicata, recorre a SecItemUpdate — um padrão de inserção ou atualização.
import Security
func upsert(_ data: Data, account: String) -> Bool {
let base: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account]
var add = base
add[kSecValueData as String] = data
let status = SecItemAdd(add as CFDictionary, nil)
if status == errSecDuplicateItem {
return SecItemUpdate(base as CFDictionary,
[kSecValueData as String: data] as CFDictionary)
== errSecSuccess
}
return status == errSecSuccess
}Lendo um item novamente
SecItemCopyMatching faz a busca. Para obter os bytes secretos, defina kSecReturnData como true e kSecMatchLimit como kSecMatchLimitOne. O resultado é retornado por meio de um parâmetro de saída como CFTypeRef.
import Security
func load(account: String) -> Data? {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account,
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitOne]
var result: CFTypeRef?
let status = SecItemCopyMatching(
query as CFDictionary, &result)
guard status == errSecSuccess else { return nil }
return result as? Data
}Atualizando um item
SecItemUpdate recebe dois dicionários: uma consulta que encontra o item e um dicionário com os atributos a serem atualizados. Somente os atributos que você listar serão alterados; todo o restante será preservado.
import Security
func update(_ newData: Data, account: String) -> Bool {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account]
let attrs: [String: Any] = [
kSecValueData as String: newData]
return SecItemUpdate(query as CFDictionary,
attrs as CFDictionary) == errSecSuccess
}Excluindo um item
SecItemDelete remove os itens correspondentes. Excluir algo que não existe retorna errSecItemNotFound, que pode ser tratado como sucesso ao limpar credenciais durante o encerramento da sessão.
import Security
func delete(account: String) -> Bool {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account]
let status = SecItemDelete(query as CFDictionary)
return status == errSecSuccess
|| status == errSecItemNotFound
}Decodificando OSStatus
Os erros são códigos inteiros de OSStatus. SecCopyErrorMessageString transforma um deles em uma descrição compreensível, o que é extremamente útil para depurar por que uma operação de gravação ou leitura falhou.
import Security
func describe(_ status: OSStatus) -> String {
return SecCopyErrorMessageString(status, nil)
as String? ?? "OSStatus \(status)"
}Identificando itens de forma exclusiva
Os itens são identificados pela combinação de seus atributos — normalmente kSecAttrService e kSecAttrAccount para senhas genéricas. Escolha uma string de serviço estável e específica do aplicativo para que segredos diferentes nunca entrem em conflito.
import Security
// Uniqueness for generic passwords usually comes from:
// service (your bundle id) + account (the username)
let service = "com.example.app.auth"
let account = "current-user"
_ = (service, account)Uma pequena camada de encapsulamento
Como a API bruta é detalhada, as equipes a encapsulam em um tipo pequeno que expõe save, read e delete. Assim, a configuração do kSec fica em um único lugar e os pontos de chamada permanecem limpos.
import Security
struct TokenStore {
let service = "com.example.app.auth"
func read(_ account: String) -> Data? {
let q: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: account,
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitOne]
var out: CFTypeRef?
return SecItemCopyMatching(q as CFDictionary, &out)
== errSecSuccess ? out as? Data : nil
}
}Verificação rápida
Relembre a forma correta de recuperar os bytes de um segredo armazenado.
Recapitulação
Você aprendeu as operações de criar, ler, atualizar e excluir no chaveiro:
- Armazene as credenciais no chaveiro criptografado, nunca em UserDefaults ou em arquivos.
- Descreva os itens com dicionários de consulta
kSec; escolha uma classe comokSecClassGenericPassword. SecItemAdd/SecItemCopyMatching/SecItemUpdate/SecItemDeleteabrangem todo o ciclo de vida; trateerrSecDuplicateItemcom uma operação de inserção ou atualização.- Identifique os itens por serviço e account, e decodifique
OSStatuspara depuração.
Perguntas Frequentes
A aula “Armazenamento de Segredos no Keychain” é grátis?
Sim — o texto completo de “Armazenamento de Segredos no Keychain” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Swift Academy, atualize para CoddyKit PRO. O curso de Swift Academy inclui 4 aulas no total.
O que vou aprender em “Armazenamento de Segredos no Keychain”?
Salve e recupere credenciais com segurança. Você pratica Swift Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Swift Academy?
Nenhuma experiência prévia é necessária. Swift Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.
Quanto tempo leva a aula “Armazenamento de Segredos no Keychain”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Swift Academy?
Sim. Cada aula de Swift Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Armazenamento de Segredos no Keychain
- Controle de Acesso ao Keychain
- Autenticação biométrica
- Proteção e criptografia de dados