Hapus item gantungan kunci saat aplikasi dihapus instalasinya

238

Saya menggunakan kode scifihifi-iphone idandersen untuk gantungan kunci dan menyimpan kata sandi

[SFHFKeychainUtils storeUsername:@"User" andPassword:@"123"
              forServiceName:@"TestService" updateExisting:YES error:&error];

Ketika saya menghapus aplikasi dari perangkat, kata sandi tetap berada di gantungan kunci.

Saya ingin menghapus kata sandi dari gantungan kunci ketika pengguna menghapus aplikasi dari perangkat. Bagaimana saya bisa melakukan ini?

enc
sumber
13
Karena kode Anda tidak berjalan ketika aplikasi Anda dihapus, Anda tidak dapat melakukan ini.
Jonathan Grynspan
1
Saya pikir Anda dapat menghapus item gantungan kunci hanya dari dalam aplikasi, tetapi tidak sebelum mencopotnya. Anda dapat melihat metode deleteItem di SFHFKeychainUtils untuk menghapus nama pengguna atau kata sandi dari gantungan kunci.
matteodv

Jawaban:

406

Anda dapat mengambil keuntungan dari fakta bahwa NSUserDefaults yang dibersihkan oleh instalasi dari sebuah aplikasi. Sebagai contoh:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //Clear keychain on first run in case of reinstallation
    if (![[NSUserDefaults standardUserDefaults] objectForKey:@"FirstRun"]) {
        // Delete values from keychain here
        [[NSUserDefaults standardUserDefaults] setValue:@"1strun" forKey:@"FirstRun"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }

    //...Other stuff that usually happens in didFinishLaunching
}

Ini memeriksa dan menetapkan kunci / nilai "FirstRun" NSUserDefaultspada saat pertama kali menjalankan aplikasi Anda jika belum ditetapkan. Ada komentar di mana Anda harus meletakkan kode untuk menghapus nilai dari gantungan kunci. Sinkronisasi dapat dipanggil untuk memastikan kunci / nilai "FirstRun" segera bertahan jika pengguna membunuh aplikasi secara manual sebelum sistem tetap ada.

Amro
sumber
2
Saya setuju dengan Amro bahwa Anda dapat menghapus / membersihkan gantungan kunci Anda saat aplikasi pertama kali dijalankan. Ini akan menghapus semua yang telah ditetapkan sebelum aplikasi dihapus instalasinya terakhir kali. Saya melakukan ini untuk salah satu aplikasi saya yang menyimpan kredensial Facebook / Twitter dan sudah berfungsi cukup baik mengetahui fakta bahwa hanya aplikasi Anda yang memiliki akses ke gantungan kunci apa pun yang telah ditetapkan.
XCool
Terima kasih atas petunjuk ini.
iOSAppDev
3
NSUserDefaults tidak dihapus ketika pengguna secara manual berhenti dari aplikasi. Hanya nilai yang telah Anda tetapkan tetapi sistem (berkala) atau Anda belum disinkronkan dengan disk (dengan menelepon synchronize) hilang dalam kasus itu. Sebaiknya panggil sinkronisasi setelah menyetel tombol jalankan pertama. Dan ya, NSUserDefaults dihapus ketika perangkat diatur ulang (dan tidak dikembalikan dari cadangan), dan itu bagus untuk kasus ini.
Amro
5
Anda salah dan Anda mungkin melakukan sesuatu yang menyebabkan default pengguna dihapus. Inti dari NSUserDefaults adalah untuk menyimpan preferensi dan mempertahankan preferensi tersebut melalui beberapa peluncuran aplikasi. Sekali lagi, mengatur ulang perangkat atau menghapus aplikasi akan menghapus default pengguna. Lihatlah berapa banyak orang yang memilih ulang jawaban ini dan memeriksa kode Anda. Lalu baca dokumentasi. Heck, kirimkan saya kode yang relevan dan saya akan menunjukkan kepada Anda apa yang Anda lakukan salah. Sudah seperti ini sejak iOS 2.0. Turunkan suara tetapi saya sarankan untuk menulis kasus uji yang terisolasi, sederhana, terlebih dahulu.
Amro
9
Saya tidak akan terlalu percaya diri menggunakan NSUserDefault untuk ini. Mengapa? Lihat utas itu: stackoverflow.com/questions/20269116/… . Jika Anda memulai aplikasi dari latar belakang, ada beberapa kasus di mana kunci khusus Anda di NSUserDefaults tidak disetel. Menerapkan jawaban ini akan menghapus kunci kustom Keychain Anda meskipun Anda benar-benar tidak menginginkannya!
Aurelien Porte
40

Untuk pengguna yang mencari versi @ amro jawaban Swift 3.0 :

let userDefaults = UserDefaults.standard

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

     // Update the flag indicator
     userDefaults.set(true, forKey: "hasRunBefore")
}

* perhatikan bahwa fungsi sinkronisasi () sudah usang

bwcooley
sumber
2
if !userDefaults.bool(forKey: "hasRunBefore") {Itu lebih bersih.
nefarianblack
1
Panggilan sinkronisasi harus dihapus.
Pochi
30

Tidak ada pemicu untuk melakukan kode ketika aplikasi dihapus dari perangkat. Akses ke gantungan kunci tergantung pada profil penyediaan yang digunakan untuk menandatangani aplikasi. Karenanya tidak ada aplikasi lain yang dapat mengakses informasi ini di gantungan kunci.

Ini tidak membantu Anda dengan tujuan untuk menghapus kata sandi di gantungan kunci ketika pengguna menghapus aplikasi dari perangkat tetapi itu akan memberi Anda kenyamanan bahwa kata sandi tidak dapat diakses (hanya dari menginstal ulang aplikasi asli).

Shane Fitzgibbon
sumber
Jadi, jika kita mengubah profil penyediaan aplikasi kita, apakah itu dapat mengakses nilai yang disimpan sebelumnya di gantungan kunci.
Moaz Saeed
27

Bagi mereka yang mencari versi Swift dari jawaban @ amro:

    let userDefaults = NSUserDefaults.standardUserDefaults()

    if userDefaults.boolForKey("hasRunBefore") == false {

        // remove keychain items here


        // update the flag indicator
        userDefaults.setBool(true, forKey: "hasRunBefore")
        userDefaults.synchronize() // forces the app to update the NSUserDefaults

        return
    }
rsc
sumber
9

Versi C # Xamarin

    const string FIRST_RUN = "hasRunBefore";
    var userDefaults = NSUserDefaults.StandardUserDefaults;
    if (!userDefaults.BoolForKey(FIRST_RUN))
    {
        //TODO: remove keychain items
        userDefaults.SetBool(true, FIRST_RUN);
        userDefaults.Synchronize();
    }

... dan untuk menghapus catatan dari gantungan kunci (komentar TODO di atas)

        var securityRecords = new[] { SecKind.GenericPassword,
                                    SecKind.Certificate,
                                    SecKind.Identity,
                                    SecKind.InternetPassword,
                                    SecKind.Key
                                };
        foreach (var recordKind in securityRecords)
        {
            SecRecord query = new SecRecord(recordKind);
            SecKeyChain.Remove(query);
        }
InquisitorJax
sumber
1
Dengan menggunakan if (VersionTracking.IsFirstLaunchEver) {// remove keychain items}dari Xamarin.Essentials Anda tidak perlu kode untuk userDefaults. Xamarin. Esensial membungkus itu untuk Anda .
Christopher Stephan
7

File akan dihapus dari direktori dokumen aplikasi Anda ketika pengguna mencopot pemasangan aplikasi. Mengetahui hal ini, yang harus Anda lakukan adalah memeriksa apakah ada file sebagai hal pertama yang terjadi application:didFinishLaunchingWithOptions:. Setelah itu, buat file tanpa syarat (meskipun itu hanya file dummy).

Jika file tidak ada pada saat pemeriksaan, Anda tahu ini adalah yang pertama kali dijalankan sejak instalasi terbaru. Jika nanti Anda perlu tahu di aplikasi, simpan hasil boolean ke anggota delegasi aplikasi Anda.

stephen
sumber
7

Jawaban @ amro diterjemahkan ke Swift 4.0:

if UserDefaults.standard.object(forKey: "FirstInstall") == nil {
    UserDefaults.standard.set(false, forKey: "FirstInstall")
    UserDefaults.standard.synchronize()
}
Muhammad Nayab
sumber
Atau bahkan if !UserDefaults.standard.bool(forKey: "FirstInstall")yang defaultnya salah jika kunci tidak ada. Dan .synchronize () tidak diperlukan.
CharlesA
3

Ini tampaknya menjadi perilaku default di iOS 10.3 berdasarkan perilaku yang orang saksikan dalam beta # 2. Belum menemukan dokumentasi resmi tentang ini, jadi silakan berkomentar jika Anda punya.

Stavash
sumber
7
Sampai beta 5 saya kira, rilis publik iOS 10.3 tidak mengandung perubahan ini.
Jakub Truhlář