1

I understand using 'NSSecureCoding' one could securely store data to disk, similar to keychain as a place for safe storage of information.

I understand also that keychain has the advantage of sharing between the applications for the same provider. If one would ignore the keychain share feature, would one be able to say, it is equally safe to store data in keychain in comparison to NSSecureCoding ?

I have a user object

class User: NSObject, NSSecureCoding {

private enum CodingKeys: String, CodingKey {
    case test
}

public static var supportsSecureCoding: Bool {

    return true
}

override init() {}

var test: String = "teeees"


func encode(with aCoder: NSCoder) {

    aCoder.encode(self.test as NSString)
}

required init?(coder aDecoder: NSCoder) {

    test = aDecoder.decodeObject(of: NSString.self, forKey: CodingKeys.test.rawValue)! as String
}
}

which I archive

let user = User()
    let data = NSKeyedArchiver.archivedData(withRootObject: user)

    try! data.write(to: DocumentHelper.cashURLForID(id: "TTYYUU"))

the content of TTYYUU is:

6270 6c69 7374 3030 d401 0203 0405 0615 1658 2476 6572 7369 6f6e 5824 6f62 6a65 6374 7359 2461 7263 6869 7665 7254 2474 6f70 1200 0186 a0a4 0708 0d0e 5524 6e75 6c6c d209 0a0b 0c52 2430 5624 636c 6173 7380 0280 0356 7465 6565 6573 d20f 1011 125a 2463 6c61 7373 6e61 6d65 5824 636c 6173 7365 735f 1011 5365 6375 7265 436f 6469 6e67 2e55 7365 72a2 1314 5f10 1153 6563 7572 6543 6f64 696e 672e 5573 6572 584e 534f 626a 6563 745f 100f 4e53 4b65 7965 6441 7263 6869 7665 72d1 1718 5472 6f6f 7480 0108 111a 232d 3237 3c42 474a 5153 555c 616c 7589 8ca0 a9bb bec3 0000 0000 0000 0101 0000 0000 0000 0019 0000 0000 0000 0000 0000 0000 0000 00c5

Could someone show the way to decode the raw information, it says the format is 'NSPropertyList Binary Format_v1_0', could one show how to extract 'teeees' from this binary?

Congruent Tech. UG
  • 1,408
  • 2
  • 12
  • 21
  • 5
    Why do you think that MSSecureCoding allows `securely store data to disk`? Do you have any reference for that? – Robert Apr 06 '18 at 13:29
  • No reference other than the name? Secure coding? I could be wrong, my question is if it would encode information in a way that is not easily readable by human/hacker – Congruent Tech. UG Apr 06 '18 at 13:30
  • 6
    No, `NSSecureCoding` is not any more secure in this sense than regular `NSCoding` (the data format is still readable) — the benefit comes when you want to read the data back from disk and are trying to prevent arbitrary code execution by not trusting the contents of the archive. Writing the data to the keychain would keep it generally private from prying eyes. – Itai Ferber Apr 06 '18 at 13:43
  • 1
    As for your second question (edited in): you can view the plist data in XML by either writing it out to disk and converting the format using `plutil`, or by creating an `NSKeyedArchiver`, setting its `.outputFormat` to `.xml`, archiving the root object, and viewing the `.encodedData` as a UTF-8 string. – Itai Ferber Apr 06 '18 at 14:45
  • @Arash see my updated answer regarding the binary data you posted. – Robert Apr 06 '18 at 15:19

1 Answers1

5

A class is not "secure" because it contains this text in it's name. Security without a detailed description how, why (e.g. encyrption, integrity protection, ..) and it's limitations is useless. The documentation explicitly states that it is only secure against object substitution attacks.

It totally this means that it is not easy to replace the file or alter the content.

There is never stated anywhere that it can be used for "securely store data to disk". Hence NSSecureCoding is used for a totally different use case compared to the Keychain which is dedicated to provide "secure storage of passwords, keys, certificates, and notes for one or more users.".

Edit: Looking at your added example of encoded data it contains a lot of plaintext data including teeees. You can look at it using any hex editor or the strings command.

Robert
  • 39,162
  • 17
  • 99
  • 152
  • Thanks for the answer, I came across the term 'object substitution attack' and I wonder if I have a 'user' object with 'name' property and I would persist it to disk with NSSecureCoding, based on your comment the attacker is still able to fetch the file, change the content of name property, and NSSecureCoding would be still able to decode the user object but with the new hacked name. Is this scenario true? If this true, then how NSCoding would make it secure?Does it make it secure just in scenarios where the schema of the object is completely changed? archived with additional phone property? – Congruent Tech. UG Apr 06 '18 at 13:49
  • 2
    @Arash Very few things (short of encrypted storage) can keep an attacker from messing with the archive itself; instead, `NSSecureCoding` sets limits on how the archive can be read from. By specifying the types that you expect in code, you prevent the attacker from replacing your `User` with a totally arbitrary object that you don’t expect. If you `[decoder decodeObjectOfClass:[User class] forKey:...`, having secure coding enabled prevents the decoding of, say, `NSAttributedString` (or any class that would otherwise be present at runtime). – Itai Ferber Apr 06 '18 at 14:13
  • Basically, it prevents most cases of blindly trusting what’s in the archive and instead puts the contract in code. There’s still more work you’d need to do on your end during decoding to make sure things are truly what you expect (some additional type validation, input validation, etc.), but this is the major benefit here. – Itai Ferber Apr 06 '18 at 14:14