İçeriğe geç

Keychain – Data Storage Testing

Keychain'in kullanımını kısaca açıklayacak olursak, kişisel olmayan verilerin saklanabileceği küçük bir depolama alanıdır. Burada token, key saklayabilirsiniz bu sayede uygulamalarda otomatik login olabilirsiniz ancak bu tarz işlemleri yaparken aatlamamanız gereken kısımlar var.

Normal bir file system'de siz uygulamayı sildiğinizde, uygulama dosyalarıda temizlenir. Ancak keychain bu şekilde çalışmamaktadır. Siz uygulamayı silseniz bile keychain içerisindeki veriler sabit kalacaktır. Bundan dolayı testler esnasında keychain içerisinde kişisel verilerin saklanmadığından emin olunulmalıdır.

Kullanılmakta olan bir telefandan bütün uygulamaların silindiğini ve başkası adına kullanılması için ödünç verildiğini düşünelim. Daha öncesinde kullanılan ve session token'ı keychain'e kaydedilmiş bir uygumayı telefonun yeni sahibi indirirse, uygulamayı başkası adına kullanmaya başlayabilir.

Aşağıda ilk olarak sadece keychain'de veri kaydeden bir uygulama örneği göreceksiniz. Kodlarını paylaştım.

//
//  ViewController.swift
//  KeychainKullanimi
//
//  Created by Beren Kuday Görün on 1.08.2022.
//

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var sonuc: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        ekle()
        oku()

    }

    func ekle()
    {
        let query = [
            kSecValueData : "topsecret".data(using: .utf8)!,
            kSecAttrAccount : "password",
            kSecClass:kSecClassGenericPassword
        ] as CFDictionary

        SecItemAdd(query, nil)

    }

    func oku()
    {
        let query = [
            kSecAttrAccount : "password",
            kSecClass:kSecClassGenericPassword,
            kSecReturnData :   true
        ] as CFDictionary

        var ref : AnyObject? = nil
        let durum = SecItemCopyMatching(query, &ref)
        if(durum == 0){
            let deger = String(data : ref as! Data, encoding: .utf8)
            sonuc.text = deger
        }
        else
        {
            sonuc.text = "Veri yok"
        }
    }

}

Şimdi bu uygulamayı daha sonrasında telefona attım ve objection ile açtım. Burada objection ile patchleme kısımlarını geçiyor. Merak edenler bununla ilgili yazıma bakabilir. Uygulamayı objectio ile çalıştırıp keychain'lere baktığımda aşağıdaki sonuçları elde ediyorum.

...enkudaygorun.KeychainKullanimi on (iPhone: 15.0) [usb] # ios keychain dump
Note: You may be asked to authenticate using the devices passcode or TouchID
Save the output by adding `--json keychain.json` to this command
Dumping the iOS keychain...
Created                    Accessible    ACL   Type      Account   Service  Data
-------------------------  ------------  ----  --------  --------  -------  ---------
2022-08-01 14:25:20 +0000  WhenUnlocked  None  Password  password           topsecret
2022-08-01 14:08:55 +0000  WhenUnlocked  None  Password  password           topsecret

Şimdi uygulayı sileceğim ve kodlarını aşağıdaki gibi değiştirip tekrardan cihaza göndereceğim. Kodlarda yaptığım şey aslında okuma ve yazma metotlarını yorum satırına almadır.

 override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        //ekle()
        //oku()

    }

İşte bu şekilde derlendikten sonra bile uygulamayı silip geri yüklediğimizde objection aracıyla keychainlerin sabit kaldığını görebileceğiz.

...enkudaygorun.KeychainKullanimi on (iPhone: 15.0) [usb] # ios keychain dump
Note: You may be asked to authenticate using the devices passcode or TouchID
Save the output by adding `--json keychain.json` to this command
Dumping the iOS keychain...
Created                    Accessible    ACL   Type      Account   Service  Data
-------------------------  ------------  ----  --------  --------  -------  ---------
2022-08-01 14:25:20 +0000  WhenUnlocked  None  Password  password           topsecret
2022-08-01 14:08:55 +0000  WhenUnlocked  None  Password  password           topsecret

Peki bu durumun önüne nasıl geçebiliriz? Bu durumun da açıklaması aşağıdaki kod örneğindedir. Eğer bir uygulama işk defa başlatılıyorsa bu tespit edildikten sonra keychain silinmelidir. böylece eski keychain kullanılamaz. Yapı aşağıdaki gibi olabilir.

let userDefaults = UserDefaults.standard

if userDefaults.bool(forKey: "hasRunBefore") == false {
    // Remove Keychain items here

    // Update the flag indicator
    userDefaults.set(true, forKey: "hasRunBefore")
    userDefaults.synchronize() // Forces the app to update UserDefaults
}
Kategori:iOSSwift

İlk Yorumu Siz Yapın

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir