Mik*_*ike 38 iphone encryption data-protection core-data ios4
我正在编写一个需要加密数据的iPhone应用程序.我已经学会了如何通过设置NSFileProtectionComplete属性来打开文件加密.我也知道如何检查iPhone版本以确保它们运行的是iOS 4.0或更高版本.
我已经意识到,如果用户没有选择密码并且没有在设置>常规>密码锁屏幕上专门启用数据保护,那么数据实际上根本不受保护.
我想弹出警告并告诉用户他们必须启用密码并启用数据保护(这需要在4前iPhone上进行备份和恢复),然后如果他们没有密码则退出应用程序并启用数据保护.我无论如何都无法弄清楚这些设置的状态.我发现的所有API,例如UIApplication中的"protectedDataAvailable",如果禁用数据保护,都会成功通过.
Hea*_*ers 18
免责声明:此答案有效期至ios 4.3.3
如果启用了数据保护,则nil NSFileProtectionKey默认情况下新创建的文件将具有.
如果关闭数据保护,则NSFileProtectionNone NSFileProtectionKey默认情况下新创建的文件将具有.
因此,您可以使用以下代码检测是否存在文件保护:
NSString *tmpDirectoryPath =
[NSHomeDirectory() stringByAppendingPathComponent:@"tmp"];
NSString *testFilePath =
[tmpDirectoryPath stringByAppendingPathComponent:@"testFile"];
[@"" writeToFile:testFilePath
atomically:YES
encoding:NSUTF8StringEncoding
error:NULL]; // obviously, do better error handling
NSDictionary *testFileAttributes =
[[NSFileManager defaultManager] attributesOfItemAtPath:testFile1Path
error:NULL];
BOOL fileProtectionEnabled =
[NSFileProtectionNone isEqualToString:[testFile1Attributes objectForKey:NSFileProtectionKey]];
Run Code Online (Sandbox Code Playgroud)
owe*_*nfi 13
iOS 8(OS X Yosemite)引入了一个新的API /常量,用于检测用户的设备是否有密码.
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly 可用于检测设备上是否设置了密码.
流程是:
我已经在我的iPhone 5S上测试了这个,首先它返回了true,然后我在设置中禁用了密码,然后它返回了false.最后,我重新启用了密码并返回true.以前的OS版本将返回false.代码在模拟器中工作,true在设置了OS X密码的机器上返回(我没有测试过替代OS X场景).
另请参阅此处的示例项目:https://github.com/project-imas/passcode-check/pull/5
最后,据我所知,iOS 8没有禁用数据保护的设置,因此我认为这是保证加密所需的全部内容.
BOOL isAPIAvailable = (&kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly != NULL);
// Not available prior to iOS 8 - safe to return false rather than crashing
if(isAPIAvailable) {
// From http://pastebin.com/T9YwEjnL
NSData* secret = [@"Device has passcode set?" dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *attributes = @{
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService: @"LocalDeviceServices",
(__bridge id)kSecAttrAccount: @"NoAccount",
(__bridge id)kSecValueData: secret,
(__bridge id)kSecAttrAccessible: (__bridge id)kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
};
// Original code claimed to check if the item was already on the keychain
// but in reality you can't add duplicates so this will fail with errSecDuplicateItem
// if the item is already on the keychain (which could throw off our check if
// kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly was not set)
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)attributes, NULL);
if (status == errSecSuccess) { // item added okay, passcode has been set
NSDictionary *query = @{
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService: @"LocalDeviceServices",
(__bridge id)kSecAttrAccount: @"NoAccount"
};
status = SecItemDelete((__bridge CFDictionaryRef)query);
return true;
}
// errSecDecode seems to be the error thrown on a device with no passcode set
if (status == errSecDecode) {
return false;
}
}
return false;
Run Code Online (Sandbox Code Playgroud)
PS正如Apple在WWDC视频中指出的那样(711 Keychain和Touch ID认证),他们选择不通过API直接提供密码状态,以防止应用程序进入他们不应该处理的情况be(即"这个设备是否有密码?好吧,很好,我将以纯文本形式存储此私人信息".创建加密密钥,存储kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly并加密该文件会更好,这将是不可恢复的如果用户决定禁用他们的密码).
| 归档时间: |
|
| 查看次数: |
9770 次 |
| 最近记录: |