如何保护iOS包文件,如plist,image,sqlite,媒体文件

时间:2014-03-01 09:57:20

标签: ios iphone bundle protection

我创建了示例hello world项目,然后将Data.plist文件添加到资源文件夹中。 现在,人们可以通过解压缩.ipa文件轻松获取捆绑文件。有没有办法保护保存在iPhone应用程序包中的Data.plist文件?

 Encryption is a decent method of scrambling the data but i don't know how to implement encription concept.

您有任何示例代码吗?

enter image description here

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Data" ofType:@"plist"];
    NSArray *arrData = [[NSArray alloc]initWithContentsOfFile:filePath];

    NSData *datas = [NSKeyedArchiver archivedDataWithRootObject:arrData];
    [datas writeToFile:filePath atomically:YES];

提取IPA文件后

enter image description here

4 个答案:

答案 0 :(得分:10)

  1. 在部署期间加密mac上的文件:

    FIRST:不要将要加密的文件添加到目标
    例如Encryption-Test.plist

    然后在您的xcode项目中添加一个shell脚本阶段,以使用openssl加密和复制文件。
    例如
    openssl enc -e -aes-256-cbc -pass pass:asdasd -in $PROJECT_DIR/test/Encryption-Test.plist -out $TARGET_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/Encryption-Test.enc

  2. 将github中的RNCryptor源文件添加到您的项目中。这使得解密openSSL加密的AES文件变得非常容易。 (谢谢抢!)https://github.com/RNCryptor/RNCryptor (Apple的CCrypt api不适合直接使用)

  3. 加载数据并解密:

  4. e.g。

    @implementation TestViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        NSString *path = [[NSBundle mainBundle] pathForResource:@"Encryption-Test" ofType:@"enc"];
        NSData *passEncryptedData =[[NSData alloc] initWithContentsOfFile:path];
        NSString *pass = @"asdasd";
    
        NSData *dataDecrypted = [RNOpenSSLDecryptor decryptData:passEncryptedData withSettings:kRNCryptorAES256Settings password:pass error:nil];
        id plist = [NSPropertyListSerialization propertyListFromData:dataDecrypted mutabilityOption:NSPropertyListImmutable format:nil errorDescription:nil];
    
        assert(plist);
        self.text.text = [plist description];
    }
    
    @end
    

    添加了完整示例:https://github.com/Daij-Djan/encryptBundleFiles

答案 1 :(得分:3)

我在上面的例子中没有成功,最终找到了一些代码,可以让你用openssl解密加密文件(实际上是任何文件)。我在文档文件夹中工作对于这个例子,我没有使用任何shell脚本。以下是如何做到这一点:

  1. 加密终端中的文件,如下所示:
  2. openssl aes-256-cbc -in questions.plist -out questions.enc
    1. 将文件拖到支持文件目录
    2. ,将文件添加到Xcode项目中
    3. 下载 RNCryptor here
    4. 在下载的项目中找到 RNCryptor 库: encryptBundleFiles-master / test / RNCryptor 并将它们添加到您的Xcode项目中
    5. RNDecryptor.h RNOpenSSLDecryptor.h 文件导入您的类文件,例如 ExampleViewController.m 文件。
    6. 在下面的代码中添加您想要调用它的代码,就像某个函数一样。

    7. 你已经完成了。您现在可以使用plist文件来填充tableview。

    8. // Copy the plist file from the resources folder to the documents folder
          NSFileManager *fileManager = [NSFileManager defaultManager];
              NSError *error;
              NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
              NSString *documentsDirectory = [paths objectAtIndex:0];

      NSString *txtPath = [documentsDirectory stringByAppendingPathComponent:@"questions.enc"]; if ([fileManager fileExistsAtPath:txtPath] == NO) { NSString *resourcePath = [[NSBundle mainBundle] pathForResource:@"questions" ofType:@"enc"]; [fileManager copyItemAtPath:resourcePath toPath:txtPath error:&error]; } NSString *filePath1 = [documentsDirectory stringByAppendingPathComponent:@"questions.encr"]; NSData *passEncryptedData =[[NSData alloc] initWithContentsOfFile:filePath1] ; NSString *pass = @"asdf"; // Insert your password from step 1 NSData *dataDecrypted = [RNOpenSSLDecryptor decryptData:passEncryptedData withSettings:kRNCryptorAES256Settings password:pass error:&error]; NSString *appFile = [documentsDirectory stringByAppendingPathComponent:@"questionsDECRYPTED.plist"]; //The Decrypted file saved here [dataDecrypted writeToFile:appFile atomically:YES];

答案 2 :(得分:0)

基于Daij-Dan的解决方案,我创建了几个Swift String扩展。需要RNCryptor

它们的用法如下:

//Decrypt a UIImage
let decryptedImage = "encyptedFileNameInBundle".decryptedImage(password: "test")

//Decrypt NSData
let decryptedData = "encyptedDataFileNameInBundle".decryptedData(password: "test")

该字符串是已添加到捆绑软件资源中的资源的文件名。假定默认情况下文件具有扩展名“ enc”,否则,请使用“ fileExtension:”传递文件扩展名。

扩展名:

public extension String {

    func decryptedImage(password: String, fileExtension: String = "enc") -> UIImage? {

         //create encypted file with:
         //openssl aes-256-cbc -in fileName.jpg -out fileName.enc

        if let decryptedData = self.decryptedData(password: password, fileExtension: fileExtension) {
            return UIImage(data: decryptedData)
        }

        return nil
     }

    func decryptedData(password: String, fileExtension: String = "enc") -> Data? {

        //create encypted file with:
        //openssl aes-256-cbc -in fileName.data -out fileName.enc

        if let fileURL = Bundle.main.url(forResource: self, withExtension: fileExtension) {

            do {
                let encyptedData = try Data(contentsOf: fileURL)
                return try RNOpenSSLDecryptor.decryptData(encyptedData, with: kRNCryptorAES256Settings, password: password)
            } catch {
                print("encryptedImage ERR: \(error.localizedDescription)")
            }
        }

        return nil
    }
}

答案 3 :(得分:-1)

使用NSKeyedArchiver从字典中创建NSData对象(NSKeyedArchiver archivedDataWithRootObject :)。然后使用AES加密NSData并将其写入您的文件。

只读取相反的过程:首先,读取NSData,通过上述链接中的方法解密,然后将解密的NSData传递给NSKeyedUnarchiver(NSKeyedUnarchiver unarchiveObjectWithData :)并返回字典。您可以使用plist文件或NSDictionary来保证数据的安全。

Example 1

Example 2

编辑2:

NSDictionary *Your_NSDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                           @"Obj1", @"Key1",
                           @"Obj2", @"Key2", nil];
//store dictionary
NSMutableData *yourData = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:Your_NSDictionary forKey: @"key"];
[archiver finishEncoding];
[yourData writeToFile:@"FilePath" atomically:YES];

NSString* filePath = [[NSBundle mainBundle] pathForResource:@"Data" 
                                                 ofType:@"plist"];
NSDictionary* data = [NSDictionary dictionaryWithContentsOfFile:filePath];
NSMutableDictionary * rootObject;
rootObject = [NSMutableDictionary dictionary];
[rootObject setValue: data forKey:@"accounts"];
[NSKeyedArchiver archiveRootObject: rootObject toFile: path];