删除钥匙链项目时,应用程序卸载

我使用idandersen的scifihifi-iphone代码的钥匙链和保存密码使用

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

当我从设备中删除应用程序时,密码仍然保留在密钥链中。

当用户从设备中删除应用程序时,我想从密钥链中删除密码。我该怎么做呢?

126426 次浏览

当应用程序从设备中删除时,没有执行代码的触发器。对keychain的访问依赖于用于对应用程序进行签名的配置文件。因此,没有其他应用程序能够访问密钥链中的此信息。

当用户从设备中删除应用程序时,它不能帮助您删除密钥链中的密码,但它应该让您感到一些安慰,即密码是不可访问的(只能从重新安装原始应用程序)。

你可以利用通过卸载应用程序来清除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
}

如果尚未设置"FirstRun"键/值,则在应用程序第一次运行时检查并设置NSUserDefaults中的"FirstRun"键/值。有一个注释,你应该把代码从钥匙串删除值。同步可以被调用,以确保“FirstRun”键/值立即被持久化,以防用户在系统持久化应用程序之前手动杀死它。

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

如果检查时文件不存在,您就知道这是最新安装后的第一次运行。如果你需要在应用程序的后面知道,保存布尔结果到你的应用程序委托成员。

对于那些寻找@amro答案的Swift版本的人:

    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
}

对于寻找@amro答案的斯威夫特3.0版本的用户:

let userDefaults = UserDefaults.standard


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


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

*注意,synchronize()函数已弃用

这似乎是iOS 10.3上基于行为人们见证了在测试版#2的默认行为。我还没有找到任何关于这方面的官方文件,所以如果你有请评论。

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();
}

... 并从钥匙链中清除记录(上面的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);
}

@amro的回答翻译为Swift 4.0:

if UserDefaults.standard.object(forKey: "FirstInstall") == nil {
UserDefaults.standard.set(false, forKey: "FirstInstall")
UserDefaults.standard.synchronize()
}

只需添加一个应用程序设置包,并实现一个切换,以重置应用程序重启或基于设置(可通过userDefaults)选择的值的钥匙链