NSSecureCoding
구현
객체 클래스
NSSecureCoding
프로토콜 추가
- decode 대신에
decodeObject(of, forKey) -> NSCoding
사용
of
에는 구조체 타입을 전달할 수 없음. 반드시 클래스로 구현된 타입 전달.(String(x) NSString(O))
- SecureCoding 사용 시 반드시 클래스를 사용해야 함
class Language: NSObject, NSCoding, NSSecureCoding {
static var supportsSecureCoding: Bool {
return true
}
let name: String
let version: Double
let logo: UIImage
func encode(with coder: NSCoder) {
coder.encode(name as NSString, forKey: "name")
coder.encode(version as NSNumber, forKey: "version")
coder.encode(logo, forKey: "logo")
}
required init?(coder: NSCoder) {
guard let nameValue = coder.decodeObject(of: NSString.self, forKey: "name") as? String else { return nil }
name = nameValue
guard let versionValue = coder.decodeObject(of: NSNumber.self, forKey: "version") else {
return nil
}
version = versionValue.doubleValue
guard let img = coder.decodeObject(of: UIImage.self, forKey: "logo") as? UIImage else { return nil }
logo = img
}
init(name: String, version: Double, logo: UIImage) {
self.name= name
self.version = version
self.logo = logo
}
}
encode
- encode에서
NSKeyedArchiver.archivedData
사용 시 requiringSecureCoding
의 값을 true로 전달
class ViewController: UIViewController {
...
func encodeObject() {
do {
guard let img = UIImage(named: "swift") else { return }
let obj = Language(name: "Swift", version: 5.9, logo: img)
let data = try NSKeyedArchiver.archivedData(withRootObject:obj, requiringSecureCoding: true)
try data.write(to: fileUrl, options: .atomic)
} catch {
print(error)
}
}
...
}
decode
- 기존의 NSCoding에서는 decode 시
NSKeyedUnarchiver.unarchiveObject
에서 타입을 지정하지 않는다. 디코딩이 완료된 객체를 타입캐스팅 하는데 이 시점에서 취약점 공격 발생 가능
- SecureCoding에서는 디코딩 시점에 타입을 명확히 지정
- 따라서 코드에서 에러가 발생하거나 취약점 공격을 당할 확률이 낮아짐
class ViewController: UIViewController {
...
func decodeObject() {
do {
let data = try Data(contentsOf: fileUrl)
if let language = try NSKeyedUnarchiver.unarchivedObject(ofClass: Language.self, from: data) {
logoImageView.image = language.logo
nameLabel.text = language.name
versionLable.text = "\(language.version)"
}
} catch {
print(error)
}
}
}