0Pricing
Swift Academy · Pelajaran

Menyimpan Rahasia di Keychain

Simpan dan ambil kredensial dengan aman.

Menyimpan Rahasia di Keychain adalah pelajaran Swift Academy gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Swift Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Swift Academy mencakup 4 pelajaran total.

Mengapa Rantai Kunci

Kata sandi, token, dan kunci tidak boleh disimpan di UserDefaults atau file biasa — semua itu mudah dibaca. Rantai Kunci adalah basis data terenkripsi untuk rahasia berukuran kecil yang dikelola OS, serta dilindungi oleh perangkat keras dan kode sandi pengguna. Inilah satu-satunya tempat yang benar untuk kredensial.

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

Item Berupa Kamus

API Layanan Rantai Kunci berbasis C: Anda menjelaskan sebuah item dengan kamus kueri [String: Any] menggunakan kunci konstan kSec.... Bentuk kamus yang sama digunakan kembali untuk add, pencarian, pembaruan, dan penghapusan.

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

Kelas Item

Kunci kSecClass memilih jenis item. kSecClassGenericPassword mencakup token dan rahasia aplikasi; kSecClassInternetPassword menyimpan kredensial server dengan atribut host atau protokol. Sebagian besar rahasia aplikasi menggunakan kata sandi generik.

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

Menambahkan Item

SecItemAdd menyisipkan item baru. Anda menyertakan data di bawah kSecValueData sebagai Data, beserta atribut yang mengidentifikasinya. Fungsi ini mengembalikan OSStatus — errSecSuccess berarti operasi berhasil.

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
}

Menangani Duplikat

Menambahkan item yang atribut pengidentifikasinya sudah ada akan mengembalikan errSecDuplicateItem. Operasi save yang tangguh mencoba SecItemAdd, lalu jika terjadi duplikat menggunakan SecItemUpdate sebagai fallback — pola 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
}

Membaca Kembali Entri

SecItemCopyMatching melakukan pencarian. Untuk mendapatkan byte rahasia, Anda harus menetapkan kSecReturnData ke true dan kSecMatchLimit ke kSecMatchLimitOne. Hasilnya dikembalikan melalui parameter keluaran sebagai 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
}

Memperbarui Entri

SecItemUpdate menerima dua kamus: kueri yang menemukan entri dan kamus atribut yang akan diperbarui. Hanya atribut yang Anda cantumkan yang berubah; atribut lainnya tetap dipertahankan.

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
}

Menghapus Entri

SecItemDelete menghapus entri yang cocok. Menghapus sesuatu yang tidak ada mengembalikan errSecItemNotFound, yang dapat Anda perlakukan sebagai keberhasilan saat menghapus kredensial ketika pengguna keluar.

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
}

Mendekode Status OS

Galat berupa kode bilangan bulat OSStatus. SecCopyErrorMessageString mengubah salah satunya menjadi deskripsi yang dapat dipahami manusia, yang sangat membantu saat men-debug alasan penyimpanan atau pembacaan gagal.

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

Mengidentifikasi Entri Secara Unik

Entri dicocokkan berdasarkan gabungan atributnya — biasanya kSecAttrService dan kSecAttrAccount untuk kata sandi generik. Pilih string layanan yang stabil dan khusus aplikasi agar rahasia yang berbeda tidak pernah bertabrakan.

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)

Pembungkus Kecil

Karena antarmuka pemrograman aplikasi mentah terlalu bertele-tele, tim membungkusnya dalam tipe kecil yang menyediakan save, read, dan delete. Dengan begitu, rangkaian kSec berada di satu tempat dan lokasi pemanggilan tetap bersih.

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

Pemeriksaan Singkat

Ingat kembali cara yang benar untuk mengambil byte rahasia yang tersimpan.

Rangkuman

Anda mempelajari operasi buat, baca, perbarui, dan hapus pada Rantai Kunci:

  • Simpan kredensial dalam Rantai Kunci terenkripsi, jangan pernah menyimpannya di UserDefaults atau berkas.
  • Jelaskan entri dengan kamus kueri kSec; pilih kelas seperti kSecClassGenericPassword.
  • SecItemAdd / SecItemCopyMatching / SecItemUpdate / SecItemDelete mencakup siklus hidup; tangani errSecDuplicateItem dengan memperbarui entri yang ada atau menyisipkan entri baru.
  • Identifikasi entri berdasarkan service + account, lalu dekode OSStatus untuk penelusuran galat.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Menyimpan Rahasia di Keychain” gratis?

Ya — teks lengkap “Menyimpan Rahasia di Keychain” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Swift Academy, upgrade ke CoddyKit PRO. Kursus Swift Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Menyimpan Rahasia di Keychain”?

Simpan dan ambil kredensial dengan aman. Kamu berlatih Swift Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Swift Academy?

Tidak diperlukan pengalaman sebelumnya. Swift Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.

Berapa lama pelajaran “Menyimpan Rahasia di Keychain” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Swift Academy ini?

Ya. Setiap pelajaran Swift Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Menyimpan Rahasia di Keychain
  2. Pengendalian Akses Keychain
  3. Autentikasi Biometrik
  4. Perlindungan Data dan Enkripsi
← Kembali ke Swift Academy