卸载应用程序时删除钥匙串项

enc*_*enc 233 objective-c keychain ios

我正在使用idandersen的scifihifi-iphone代码进行钥匙串和使用保存密码

[SFHFKeychainUtils storeUsername:@"User" andPassword:@"123"
              forServiceName:@"TestService" updateExisting:YES error:&error];
Run Code Online (Sandbox Code Playgroud)

当我从设备中删除应用程序时,密码仍保留在钥匙串中.

我想在用户从设备中删除应用程序时从密钥链中删除密码.我怎样才能做到这一点?

Amr*_*mro 396

你可以利用这一事实的优点NSUserDefaults 通过一个应用程序的卸载清除.例如:

- (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
}
Run Code Online (Sandbox Code Playgroud)

NSUserDefaults如果尚未设置,则会在应用的首次运行时检查并设置"FirstRun"键/值.有一个注释,你应该放置代码来删除钥匙串中的值.可以调用Synchronize以确保"FirstRun"键/值立即保留,以防用户在系统持续存在之前手动杀死应用程序.

  • 我不会非常有信心使用NSUserDefault.为什么?看看那个帖子:http://stackoverflow.com/questions/20269116/nsuserdefaults-loosing-its-keys-values-when-phone-is-rebooted-but-not-unlocked.如果您从后台启动应用程序,则有时您的NSUserDefaults中的自定义键未设置.应用此答案将导致删除您的钥匙串自定义键,虽然您真的不想要! (9认同)
  • 你错了,你可能正在做一些导致用户默认值被清除的事情.NSUserDefaults的重点是保存首选项,并通过多个应用程序启动来保持这些首选项.同样,重置设备或删除应用程序将删除用户默认值.看看有多少人投了这个答案并检查了你的代码.然后去阅读文档.哎呀,把相关代码发给我,我会告诉你你做错了什么.从iOS 2.0开始就是这样.向下投票,但我建议先写一个孤立的,简单的测试用例. (5认同)
  • 用户手动退出应用程序时,不会清除NSUserDefaults.在这种情况下,只有你设置的值,但系统(定期)或你还没有与磁盘同步(通过调用```synchronize```).在设置第一个运行键后调用synchronize是个好主意.是的,当设备重置(而不是从备份恢复)时,NSUserDefaults被清除,在这种情况下这很好. (3认同)
  • 我同意Amro的观点,您可以在首次运行该应用程序时删除/清除钥匙串。这将清除上一次卸载该应用程序之前设置的所有内容。我为存储Facebook / Twitter凭据的其中一个应用程序执行了此操作,并且知道只有您的应用程序才能访问设置的任何钥匙串,因此它的运行状况一直很好。 (2认同)

bwc*_*ley 35

对于寻找Swift 3.0版本@ amro的答案的用户:

let userDefaults = UserDefaults.standard

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

     // Update the flag indicator
     userDefaults.set(true, forKey: "hasRunBefore")
}
Run Code Online (Sandbox Code Playgroud)

  • ```if!userDefaults.bool(forKey:"hasRunBefore"){```它只是更干净. (2认同)

Sha*_*bon 29

从设备删除应用程序时,没有触发器来执行代码.对钥匙串的访问取决于用于签署应用程序的供应配置文件.因此,没有其他应用程序能够访问钥匙串中的此信息.

当用户从设备中删除应用程序时,您无意中删除密钥链中的密码,但它应该让您感到安慰,即无法访问密码(仅限重新安装原始应用程序).

  • 因此,如果我们更改应用程序的配置文件,它是否能够访问之前存储在钥匙串中的值。 (2认同)

rsc*_*rsc 27

对于那些寻找Swift版@ 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
    }
Run Code Online (Sandbox Code Playgroud)


Inq*_*Jax 9

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();
    }
Run Code Online (Sandbox Code Playgroud)

...并清除钥匙串中的记录(上面的TODO评论)

        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);
        }
Run Code Online (Sandbox Code Playgroud)

  • 通过使用 Xamarin.Essentials 中的“if (VersionTracking.IsFirstLaunchEver) {//删除钥匙串项}”,您不需要“userDefaults”的代码。[Xamarin.Essentials 为您包装了该内容](https://github.com/xamarin/Essentials/blob/ac795bc661770695f541c5f57121128f3e7bd82f/Xamarin.Essentials/VersionTracking/VersionTracking.shared.cs#L20)。 (2认同)

ste*_*hen 6

当用户卸载应用程序时,文件将从应用程序的文档目录中删除.知道了这一点,你所要做的就是检查文件是否存在是第一件事application:didFinishLaunchingWithOptions:.然后,无条件地创建文件(即使它只是一个虚拟文件).

如果检查时文件不存在,您知道这是自最新安装以来的第一次运行.如果您稍后需要在应用程序中知道,请将布尔结果保存到您的应用程序委托成员.


Muh*_*yab 6

@ amro的答案翻译成Swift 4.0:

if UserDefaults.standard.object(forKey: "FirstInstall") == nil {
    UserDefaults.standard.set(false, forKey: "FirstInstall")
    UserDefaults.standard.synchronize()
}
Run Code Online (Sandbox Code Playgroud)