Как защитить файлы пакета iOS, такие как plist, image, sqlite, media files
Я создал образец проекта hello world, а затем добавил файл Data.plist в папку ресурсов.
Теперь люди могут легко получить файлы пакета, распакуя файл .ipa. Есть ли способ защитить файл Data.plist, который сохраняется в комплекте приложений iPhone?
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]()
Ответы
Ответ 1
-
зашифровать файлы на Mac... во время развертывания:
FIRST: не добавляйте файлы для шифрования в целевой
например Encryption-Test.plist
Затем добавьте фазу оболочки script к вашему проекту xcode, чтобы использовать 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
-
добавить исходные файлы RNCryptor из github в ваш проект. Это делает дешифровку openSSL зашифрованных файлов AES очень просто. (Спасибо rob!) https://github.com/RNCryptor/RNCryptor
(Apple CCrypt api не очень удобно работать напрямую)
-
загружать данные и расшифровывать их:
например.
@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
Ответ 2
Я успешно справился с приведенными выше примерами и, наконец, нашел код, который позволяет вам расшифровать зашифрованный файл (на самом деле, файл) с помощью openssl. Я работаю в папке с документами для этого пример, и я не использую никаких сценариев оболочки. Вот как это сделать:
- Зашифруйте свой файл в терминале следующим образом:
openssl aes-256-cbc -in questions.plist -out questions.enc
- Добавьте файл в проект Xcode, перетащив их в каталог поддерживающих файлов
- Загрузите библиотеку RNCryptor здесь.
- Найдите библиотеку RNCryptor в загруженном проекте: encryptBundleFiles-master/test/RNCryptor и добавьте их в проект Xcode.
- Импортируйте файлы RNDecryptor.h и RNOpenSSLDecryptor.h в ваш файл класса, например файл ExampleViewController.m.
-
Добавьте код ниже, из которого вы хотите его вызвать, например, определенную функцию.
-
И все готово. Теперь вы можете использовать файл plist, чтобы, например, заполнить таблицу.
// 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];
Ответ 3
На основе решения 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
}
}
Ответ 4
Используйте NSKeyedArchiver для создания объекта NSData из вашего словаря (NSKeyedArchiver archivedDataWithRootObject:). Затем зашифруйте NSData с помощью AES и напишите это в свой файл.
Чтение только обратного процесса: сначала прочитайте NSData, расшифруйте его с помощью метода из указанной ссылки, затем передайте расшифрованные NSData NSKeyedUnarchiver (NSKeyedUnarchiver unarchiveObjectWithData:), и вы вернете свой словарь. Это можно использовать для файла plist или NSDictionary для обеспечения безопасности ваших данных.
Пример 1:
Пример 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];