캡슐화는 강력한 경계를 그리는 것입니다. 웹 브라우저에서는 사용자의 모바일 코드가 다른 모바일 코드에 의해 오용되지 않도록 하는 것을 의미합니다. 서버에서는 검증된 데이터와 검증되지 않은 데이터, 한 사용자의 데이터와 다른 사용자의 데이터, 데이터 사용자가 볼 수 있는 데이터와 볼 수 없는 데이터 간의 차별화를 의미할 수 있습니다.
NSFileManager
인스턴스와 연결된 NSDictionary
의 NSFileProtectionKey
키 값으로 할당되는 상수로 NSFileManager
에 대해 정의됩니다. setAttributes:ofItemAtPath:error:
, attributesOfItemAtPath:error:
, createFileAtPath:contents:attributes:
등의 NSFileManager
함수를 사용하면 파일을 만들거나 파일의 데이터 보호 클래스를 수정할 수 있습니다. 또한 NSData
개체에 대해서도 해당하는 데이터 보호 상수가 NSDataWritingOptions
로 정의되며, 이는 NSData
함수 writeToURL:options:error:
및 writeToFile:options:error:
에 options
인수로 전달할 수 있습니다. 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
인스턴스와 연결된 Dictionary
의 NSFileProtectionKey
키 값으로 할당되는 상수로 NSFileManager
에서 정의됩니다. setAttributes(_:ofItemAtPath:)
, attributesOfItemAtPath(_:)
, createFileAtPath(_:contents:attributes:)
등의 NSFileManager
함수를 사용하면 파일을 만들거나 파일의 데이터 보호 클래스를 수정할 수 있습니다. 또한 NSDataWritingOptions
열거의 NSData
개체에 대해서도 해당하는 데이터 보호 상수가 정의됩니다. 이 상수는 NSData
함수에 대한 options
인수로 전달할 수 있으며, 해당 함수는
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
인스턴스와 연결된 NSDictionary
의 NSFileProtectionKey
키 값으로 할당되는 상수로 NSFileManager
에 대해 정의됩니다. setAttributes:ofItemAtPath:error:
, attributesOfItemAtPath:error:
, createFileAtPath:contents:attributes:
등의 NSFileManager
함수를 사용하면 파일을 만들거나 파일의 데이터 보호 클래스를 수정할 수 있습니다. 또한 NSData
개체에 대해서도 해당하는 데이터 보호 상수가 NSDataWritingOptions
로 정의되며, 이는 NSData
함수 writeToURL:options:error:
및 writeToFile:options:error:
에 options
인수로 전달할 수 있습니다. NSFileManager
및 NSData
에 지정되는 다양한 데이터 보호 클래스 상수의 정의는 다음과 같습니다.NSFileProtectionComplete
, NSDataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingFileProtectionNone
:NSFileProtectionNone
을 지정하면 장치의 UID만을 토대로 파생된 키를 사용하여 암호화됩니다. 이렇게 되면 암호로 잠겨 있는 경우나 부팅할 때를 비롯해 장치가 켜져 있을 때는 언제든지 이러한 파일에 접근할 수 있게 됩니다. 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
키 값으로 할당되는 상수로 정의됩니다. setAttributes(_:ofItemAtPath:)
, attributesOfItemAtPath(_:)
, createFileAtPath(_:contents:attributes:)
등의 NSFileManager
함수를 사용하면 파일을 만들거나 파일의 데이터 보호 클래스를 수정할 수 있습니다. 또한 NSDataWritingOptions
열거의 NSData
개체에 대해서도 해당하는 데이터 보호 상수가 정의됩니다. 이 상수는 NSData
함수에 대한 options
인수로 전달할 수 있으며, 이러한 함수로는
writeToFile(_:options:)
등이 있습니다. NSFileManager
및 NSData
에 지정되는 다양한 데이터 보호 클래스 상수의 정의는 다음과 같습니다.NSFileProtectionComplete
, NSDataWritingOptions.DataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingOptions.DataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingOptions.DataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingOptions.DataWritingFileProtectionNone
:NSFileProtectionNone
을 지정하면 장치의 UID만을 토대로 파생된 키를 사용하여 암호화됩니다. 이렇게 되면 암호로 잠겨 있는 경우나 부팅할 때를 비롯해 장치가 켜져 있을 때는 언제든지 이러한 파일에 접근할 수 있게 됩니다. 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
을 지정하면 장치의 UID만을 기반으로 하여 파생된 키를 사용하여 암호화됩니다. 이렇게 되면 암호로 잠겨 있는 경우나 부팅할 때를 비롯해 장치가 켜져 있을 때는 언제든지 이러한 파일에 접근할 수 있게 됩니다. 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
을 지정하면 장치의 UID만을 기반으로 하여 파생된 키를 사용하여 암호화됩니다. 이렇게 되면 암호로 잠겨 있는 경우나 부팅할 때를 비롯해 장치가 켜져 있을 때는 언제든지 이러한 파일에 접근할 수 있게 됩니다. 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)
...