inVINCEable
inVINCEable

Reputation: 2206

Save pictures in swift where users can't access

I have an application that allows the user to take a photo and it saves immediately, however they are currently stored in the application documents directory which is accessible through programs like iFunBox. Here is how I save the images.

        var imageName = "SomeGeneratedImageName.jpeg"
        let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
        let documentsDirectory = paths.objectAtIndex(0) as NSString
        let path = documentsDirectory.stringByAppendingPathComponent(imageName)
        var data = UIImageJPEGRepresentation(image, 1)
        data.writeToFile(path, atomically: true)

Where do I save images so the user cannot access them even through programs such as iFunBox?

UPDATE - Answer Used

Based of of zaph's answer i encrypted the pictures before saving and when reading, using RNEncrytor Here is my save function:

        var imageName = "someImageName.jpeg"
        let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
        let documentsDirectory = paths.objectAtIndex(0) as NSString
        let path = documentsDirectory.stringByAppendingPathComponent(imageName)
        var data = UIImageJPEGRepresentation(image, 1) //change 1 for compression
        let encryptedData = RNEncryptor.faireseEncryptData(data, password: "password", error: nil)
        encryptedData.writeToFile(path, atomically: true)

and

    var imageName = "thatSameImageName.jpeg"
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
    let documentsDirectory = paths.objectAtIndex(0) as NSString
    let path = documentsDirectory.stringByAppendingPathComponent(imageName)
    var decryptedImg = RNDecryptor.faireseDecryptData(NSData(contentsOfFile: path), password: "theSamePass", error: nil)
    if(decryptedImg != nil) {
        //alert
    var image: UIImage? = UIImage(data: decryptedImg)
}

also to get this to work in swift there was some issue with the AES256 so i added some classes to the RNEncryptor.h, RNEncryptor.m, RNDecryptor.h, and the RNDecryptor.m

//To RNEncrpytor.h
+ (NSData *)faireseEncryptData:(NSData *)data password:(NSString *)password error:(NSError **)error;

.

//To RNEncryptor.m
+ (NSData *)faireseEncryptData:(NSData *)data password:(NSString *)password error:(NSError **)error {
return [RNEncryptor encryptData:data withSettings:kRNCryptorAES256Settings password:password error:error]; }

.

//To RNDecryptor.h
+ (NSData *)faireseDecryptData:(NSData *)data password:(NSString *)password error:(NSError **)error;

.

//TO RNDecryptor.m
+ (NSData *)faireseDecryptData:(NSData *)data password:(NSString *)password error:(NSError **)error {
return [RNDecryptor decryptData:data withSettings:kRNCryptorAES256Settings password:password error:error]; }

Upvotes: 2

Views: 1378

Answers (2)

zaph
zaph

Reputation: 112873

Save with writeToFile:options:error: with a NSDataWritingOptions of NSDataWritingFileProtectionComplete or explicitly encrypt and decrypt as needed saving the password in the Keychain, see RNCryptor for a good encryption routine.

Generally saving large data items in a database is not a good solution.

Upvotes: 4

Shamas S
Shamas S

Reputation: 7549

If you save it anywhere on device, the users can access them.

So there are two roads that you can take at this fork. Keep it encrypted when you save it to device. And decrypt when your application wants to. (look up sqlCipher for iPhone it's super safe) Keep it at the server, and only download to show, but never save.

Upvotes: 2

Related Questions