0Pricing
Swift Academy · Leçon

Stocker des secrets dans le trousseau

Enregistrez et récupérez les identifiants en toute sécurité.

Stocker des secrets dans le trousseau est une leçon Swift Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Swift Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Swift Academy comprend 4 leçons au total.

Pourquoi utiliser le trousseau

Les mots de passe, les jetons et les clés ne doivent jamais être stockés dans UserDefaults ni dans des fichiers ordinaires : ils sont faciles à lire. Le trousseau est une base de données chiffrée, gérée par le système, destinée aux petits secrets et protégée par le matériel ainsi que par le code de l’utilisateur. C’est le seul emplacement approprié pour les identifiants.

import Security
// Keychain stores secrets encrypted at rest,
// survives app updates, and gates access by policy.

Les éléments sont des dictionnaires

L’API des services du trousseau est basée sur le langage C : vous décrivez un élément avec un dictionnaire de requête [String: Any] utilisant des clés constantes kSec.... La même structure de dictionnaire est réutilisée pour ajouter, rechercher, mettre à jour et supprimer un élément.

import Security
let query: [String: Any] = [
    kSecClass as String: kSecClassGenericPassword,
    kSecAttrAccount as String: "user@example.com",
    kSecAttrService as String: "com.example.app"
]
_ = query

Classes d’éléments

La clé kSecClass sélectionne le type d’élément. kSecClassGenericPassword couvre les jetons et secrets de l’app ; kSecClassInternetPassword stocke les identifiants de serveur avec des attributs d’hôte et de protocole. La plupart des secrets d’app utilisent le mot de passe générique.

import Security
// kSecClassGenericPassword   -> tokens, API keys
// kSecClassInternetPassword  -> server logins
// kSecClassKey / Certificate -> crypto material
let cls = kSecClassGenericPassword
_ = cls

Ajouter un élément

SecItemAdd insère un nouvel élément. Vous fournissez les données sous kSecValueData au format Data, ainsi que les attributs qui permettent de l’identifier. La fonction renvoie un OSStatus ; errSecSuccess signifie que l’opération a réussi.

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
}

Gérer les doublons

Ajouter un élément dont les attributs d’identification existent déjà renvoie errSecDuplicateItem. Un enregistrement robuste tente SecItemAdd et, en cas de doublon, se rabat sur SecItemUpdate : c’est un modèle upsert.

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
}

Relire un élément

SecItemCopyMatching effectue la recherche. Pour obtenir les octets secrets, vous devez définir kSecReturnData sur true et kSecMatchLimit sur kSecMatchLimitOne. Le résultat est renvoyé via un paramètre de sortie sous forme de 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
}

Mettre à jour un élément

SecItemUpdate accepte deux dictionnaires : une requête qui trouve l’élément et un dictionnaire des attributs à mettre à jour. Seuls les attributs que vous indiquez sont modifiés ; tous les autres sont conservés.

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
}

Supprimer un élément

SecItemDelete supprime les éléments correspondants. La suppression d’un élément inexistant renvoie errSecItemNotFound, que vous pouvez traiter comme une réussite lorsque vous effacez les identifiants lors de la déconnexion.

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
}

Décoder OSStatus

Les erreurs sont des codes entiers OSStatus. SecCopyErrorMessageString transforme un code en description compréhensible, ce qui est extrêmement utile pour comprendre pourquoi un enregistrement ou une lecture a échoué.

import Security
func describe(_ status: OSStatus) -> String {
    return SecCopyErrorMessageString(status, nil)
        as String? ?? "OSStatus \(status)"
}

Identifier les éléments de manière unique

Les éléments sont mis en correspondance selon leur combinaison d’attributs — généralement kSecAttrService et kSecAttrAccount pour les mots de passe génériques. Choisissez une chaîne de service stable et propre à l’application afin que différents secrets n’entrent jamais en conflit.

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)

Un petit conteneur

Comme l’API brute est verbeuse, les équipes l’encapsulent dans un petit type qui expose save, read et delete. La procédure kSec reste ainsi regroupée au même endroit et les points d’appel restent clairs.

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
    }
}

Vérification rapide

Rappelez-vous la bonne manière de récupérer les octets d’un secret enregistré.

Récapitulatif

Vous avez appris les opérations de création, lecture, mise à jour et suppression avec le Trousseau :

  • Stockez les identifiants dans le Trousseau chiffré, jamais dans UserDefaults ni dans des fichiers.
  • Décrivez les éléments avec des dictionnaires de requête kSec ; choisissez une classe telle que kSecClassGenericPassword.
  • SecItemAdd / SecItemCopyMatching / SecItemUpdate / SecItemDelete couvrent le cycle de vie ; gérez errSecDuplicateItem avec une opération de mise à jour ou d’insertion.
  • Identifiez les éléments par service et compte, puis décodez OSStatus pour le débogage.

Questions Fréquemment Posées

La leçon « Stocker des secrets dans le trousseau » est-elle gratuite ?

Oui — le texte complet de « Stocker des secrets dans le trousseau » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Swift Academy, passe à CoddyKit PRO. Le cours Swift Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Stocker des secrets dans le trousseau » ?

Enregistrez et récupérez les identifiants en toute sécurité. Tu pratiques Swift Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Swift Academy ?

Aucune expérience préalable n'est requise. Swift Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.

Combien de temps prend la leçon « Stocker des secrets dans le trousseau » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Swift Academy ?

Oui. Chaque leçon Swift Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Stocker des secrets dans le trousseau
  2. Contrôle d’accès au trousseau
  3. Authentification biométrique
  4. Protection des données et chiffrement
← Retour à Swift Academy