封装即绘制强边界。在 Web 浏览器中,这可能意味着确保您的移动代码不会被其他移动代码滥用。在服务器上,这可能意味着区分已验证数据和未验证数据、区分一个用户的数据和另一个用户的数据,或者区分允许用户查看的数据和不允许用户查看的数据。
NSFileManager
的数据保护类会定义为常量,以便在与 NSFileManager
实例相关联的 NSDictionary
中指定为 NSFileProtectionKey
键的值,并可通过使用 NSFileManager
函数(包括 setAttributes:ofItemAtPath:error:
、attributesOfItemAtPath:error:
和 createFileAtPath:contents:attributes:
)创建文件或修改其数据保护类。此外,NSData
对象的相应数据保护常量会定义为 NSDataWritingOptions
,并可将其作为 options
参数传递到 NSData
函数 writeToURL:options:error:
和 writeToFile:options:error:
。NSFileManager
和 NSData
的各种数据保护类常量定义如下:NSFileProtectionComplete
, NSDataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingFileProtectionNone
:NSFileProtectionCompleteUnlessOpen
或 NSFileProtectionCompleteUntilFirstUserAuthentication
标记一个文件,就会使用从用户密码或设备 UID 派生的密钥对其进行加密,但在某些情况下依然可以访问数据。因此,应该对 NSFileProtectionCompleteUnlessOpen
或 NSFileProtectionCompleteUntilFirstUserAuthentication
的用法进行仔细审核,以确定是否需要使用 NSFileProtectionComplete
执行进一步保护。例 2:以下例子中,给定的数据仅在用户首次打开设备和提供密码前受保护(直到下次重新引导):
...
filepath = [self.GetDocumentDirectory stringByAppendingPathComponent:self.setFilename];
...
NSDictionary *protection = [NSDictionary dictionaryWithObject:NSFileProtectionCompleteUntilFirstUserAuthentication forKey:NSFileProtectionKey];
...
[[NSFileManager defaultManager] setAttributes:protection ofItemAtPath:filepath error:nil];
...
BOOL ok = [testToWrite writeToFile:filepath atomically:YES encoding:NSUnicodeStringEncoding error:&err];
...
...
filepath = [self.GetDocumentDirectory stringByAppendingPathComponent:self.setFilename];
...
NSData *textData = [textToWrite dataUsingEncoding:NSUnicodeStingEncoding];
...
BOOL ok = [textData writeToFile:filepath options:NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication error:&err];
...
NSFileManager
中定义为常量,以便在与 NSFileManager
实例相关联的 Dictionary
中指定为 NSFileProtectionKey
密钥的值,而且通过使用 NSFileManager
函数(包括 setAttributes(_:ofItemAtPath:)
、attributesOfItemAtPath(_:)
和 createFileAtPath(_:contents:attributes:)
),可以创建文件或者修改其数据保护级别。此外,已在 NSDataWritingOptions
枚举中定义了 NSData
对象的相应数据保护常量,它可以作为 options
参数传递到 NSData
函数(
writeToFile(_:options:)
)。NSFileManager
和 NSData
的各种数据保护类常量定义如下:NSFileProtectionComplete
, NSDataWritingOptions.DataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingOptions.DataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingOptions.DataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingOptions.DataWritingFileProtectionNone
:NSFileProtectionCompleteUnlessOpen
或 NSFileProtectionCompleteUntilFirstUserAuthentication
标记一个文件,就会使用从用户密码或设备 UID 派生的密钥对其进行加密,但在某些情况下依然可以访问数据。因此,应该对 NSFileProtectionCompleteUnlessOpen
或 NSFileProtectionCompleteUntilFirstUserAuthentication
的用法进行仔细审核,以确定是否需要使用 NSFileProtectionComplete
执行进一步保护。示例 2:在以下示例中,给定数据仅在用户首次打开设备和提供密码前受保护(直到下次重新引导):
...
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let filename = "\(documentsPath)/tmp_activeTrans.txt"
let protection = [NSFileProtectionKey: NSFileProtectionCompleteUntilFirstUserAuthentication]
do {
try NSFileManager.defaultManager().setAttributes(protection, ofItemAtPath: filename)
} catch let error as NSError {
NSLog("Unable to change attributes: \(error.debugDescription)")
}
...
BOOL ok = textToWrite.writeToFile(filename, atomically:true)
...
...
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let filename = "\(documentsPath)/tmp_activeTrans.txt"
...
BOOL ok = textData.writeToFile(filepath, options: .DataWritingFileProtectionCompleteUntilFirstUserAuthentication);
...
kSecAttrAccessible
键的值。下面列出了各种密钥链可访问性常量的定义:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAfterFirstUnlock
标记一个密钥链项目,就会使用从用户密码或设备 UID 派生的密钥对其进行加密,但在某些情况下依然可以访问数据。因此,应该对 kSecAttrAccessibleAfterFirstUnlock
的用法进行仔细审核,以确定是否需要执行进一步保护。
...
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSData *token = [@"secret" dataUsingEncoding:NSUTF8StringEncoding];
// Configure KeyChain Item
[dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id) kSecClass];
[dict setObject:token forKey:(__bridge id)kSecValueData];
...
[dict setObject:(__bridge id)kSecAttrAccessibleAfterFirstUnlock forKey:(__bridge id) kSecAttrAccessible];
OSStatus error = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);
...
kSecAttrAccessible
键的值。下面列出了各种密钥链可访问性常量的定义:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAfterFirstUnlock
标记一个密钥链项目,就会使用从用户密码或设备 UID 派生的密钥对其进行加密,但在某些情况下依然可以访问数据。因此,应该对 kSecAttrAccessibleAfterFirstUnlock
的用法进行仔细审核,以确定是否需要执行进一步保护。
...
// Configure KeyChain Item
let token = "secret"
var query = [String : AnyObject]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecValueData as String] = token as AnyObject?
...
query[kSecAttrAccessible as String] = kSecAttrAccessibleAfterFirstUnlock
SecItemAdd(query as CFDictionary, nil)
...
NSFileManager
的数据保护类会定义为常量,以便在与 NSFileManager
实例相关联的 NSDictionary
中指定为 NSFileProtectionKey
键的值,并可通过使用 NSFileManager
函数(包括 setAttributes:ofItemAtPath:error:
、attributesOfItemAtPath:error:
和 createFileAtPath:contents:attributes:
)创建文件或修改其数据保护类。此外,NSData
对象的相应数据保护常量会定义为 NSDataWritingOptions
,并可将其作为 options
参数传递到 NSData
函数 writeToURL:options:error:
和 writeToFile:options:error:
。NSFileManager
和 NSData
的各种数据保护类常量定义如下:NSFileProtectionComplete
, NSDataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingFileProtectionNone
:NSFileProtectionNone
结果。这使此文件在设备打开时随时可以进行访问,包括用密码锁定或正在引导时。因此,应该对 NSFileProtectionNone
的用法进行仔细审核,以确定是否需要执行更严格的数据保护。例 2:在以下例子中,给定数据不受保护(设备打开时可随时访问):
...
filepath = [self.GetDocumentDirectory stringByAppendingPathComponent:self.setFilename];
...
NSDictionary *protection = [NSDictionary dictionaryWithObject:NSFileProtectionNone forKey:NSFileProtectionKey];
...
[[NSFileManager defaultManager] setAttributes:protection ofItemAtPath:filepath error:nil];
...
BOOL ok = [testToWrite writeToFile:filepath atomically:YES encoding:NSUnicodeStringEncoding error:&err];
...
...
filepath = [self.GetDocumentDirectory stringByAppendingPathComponent:self.setFilename];
...
NSData *textData = [textToWrite dataUsingEncoding:NSUnicodeStingEncoding];
...
BOOL ok = [textData writeToFile:filepath options:NSDataWritingFileProtectionNone error:&err];
...
NSFileManager
中定义为常量,以便在与 NSFileManager
实例相关联的 Dictionary
中指定为 NSFileProtectionKey
密钥的值。通过使用 NSFileManager
函数(包括 setAttributes(_:ofItemAtPath:)
、attributesOfItemAtPath(_:)
和 createFileAtPath(_:contents:attributes:)
),可以创建文件或者修改其数据保护级别。此外,已在 NSDataWritingOptions
枚举中定义了 NSData
对象的相应数据保护常量,它可以作为 options
参数传递到 NSData
函数(例如
writeToFile(_:options:)
)。NSFileManager
和 NSData
的各种数据保护类常量定义如下:NSFileProtectionComplete
, NSDataWritingOptions.DataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingOptions.DataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingOptions.DataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingOptions.DataWritingFileProtectionNone
:NSFileProtectionNone
结果。这使此文件在设备打开时随时可以进行访问,包括用密码锁定或正在引导时。因此,应该对 NSFileProtectionNone
的用法进行仔细审核,以确定是否需要执行更严格的数据保护。示例 2:在以下示例中,给定数据不受保护(设备打开时可随时访问):
...
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let filename = "\(documentsPath)/tmp_activeTrans.txt"
let protection = [NSFileProtectionKey: NSFileProtectionNone]
do {
try NSFileManager.defaultManager().setAttributes(protection, ofItemAtPath: filename)
} catch let error as NSError {
NSLog("Unable to change attributes: \(error.debugDescription)")
}
...
BOOL ok = textToWrite.writeToFile(filename, atomically:true)
...
...
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let filename = "\(documentsPath)/tmp_activeTrans.txt"
...
BOOL ok = textData.writeToFile(filepath, options: .DataWritingFileProtectionNone);
...
kSecAttrAccessible
键的值。下面列出了各种密钥链可访问性常量的定义:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAlways
结果。这使此文件在设备打开时随时可以进行访问,包括用密码锁定或正在引导时。因此,应该对 kSecAttrAccessibleAlways
的用法进行仔细审核,以确定是否需要执行更严格的密钥链可访问性级别。
...
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSData *token = [@"secret" dataUsingEncoding:NSUTF8StringEncoding];
// Configure KeyChain Item
[dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id) kSecClass];
[dict setObject:token forKey:(__bridge id)kSecValueData];
...
[dict setObject:(__bridge id)kSecAttrAccessibleAlways forKey:(__bridge id) kSecAttrAccessible];
OSStatus error = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);
...
kSecAttrAccessible
键的值。下面列出了各种密钥链可访问性常量的定义:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAlways
结果。这使此文件在设备打开时随时可以进行访问,包括用密码锁定或正在引导时。因此,应该对 kSecAttrAccessibleAlways
的用法进行仔细审核,以确定是否需要执行更严格的密钥链可访问性级别。
...
// Configure KeyChain Item
let token = "secret"
var query = [String : AnyObject]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecValueData as String] = token as AnyObject?
...
query[kSecAttrAccessible as String] = kSecAttrAccessibleAlways
SecItemAdd(query as CFDictionary, nil)
...
Realm
数据库的连接:
Realm realm = Realm.getDefaultInstance();
Realm
数据库的连接:
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];
Realm
数据库的连接:
let realm = try! Realm()
UIImageWriteToSavedPhotosAlbum
将图像保存到相册:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// Access the uncropped image from info dictionary
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// Save image
UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
...
}
UIImageWriteToSavedPhotosAlbum
将图像保存到相册:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.contentMode = .ScaleAspectFit
imageView.image = pickedImage
}
// Save image
UIImageWriteToSavedPhotosAlbum(pickedImage!, self, nil, nil)
dismissViewControllerAnimated(true, completion: nil)
}
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
等较安全的策略存储,那么如果您的设备在设置了密码的情况下被盗,则盗窃者需要解锁设备才能将密钥链项目解除锁定。如果无法输入正确的密码,盗窃者便无法解密密钥链项目。但是,如果没有设置密码,则攻击者只需滑动手指即可对设备解除锁定,并获得密钥链来解密其项目。因此,如果不强制要求为设备设置密码,则可能会削弱密钥链加密机制的安全性。
...
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSData *token = [@"secret" dataUsingEncoding:NSUTF8StringEncoding];
// Configure KeyChain Item
[dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id) kSecClass];
[dict setObject:token forKey:(__bridge id)kSecValueData];
...
[dict setObject:(__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly forKey:(__bridge id) kSecAttrAccessible];
OSStatus error = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);
...
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
等较安全的策略存储,那么如果您的设备在设置了密码的情况下被盗,则盗窃者需要解锁设备才能将密钥链项目解除锁定。如果无法输入正确的密码,盗窃者便无法解密密钥链项目。但是,如果没有设置密码,则攻击者只需滑动手指即可对设备解除锁定,并获得密钥链来解密其项目。因此,如果不强制要求为设备设置密码,则可能会削弱密钥链加密机制的安全性。
...
// Configure KeyChain Item
let token = "secret"
var query = [String : AnyObject]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecValueData as String] = token as AnyObject?
...
query[kSecAttrAccessible as String] = kSecAttrAccessibleWhenUnlockedThisDeviceOnly
SecItemAdd(query as CFDictionary, nil)
...