IOSデータベース保護





データベースに保存された情報の脆弱性は、iOSアプリケーションの最も一般的なセキュリティ問題の1つです。 多くのプログラムは、パスワードを使用してデータにアクセスするようユーザーに提供しますが、ほとんどの場合、これは情報の保存方法に影響を与えません。 したがって、パスワードマネージャー、メモ帳、オーガナイザー、財務トラッカーなどのアプリケーションのデータには、デバイスを手にしたほとんどすべての部外者がアクセスできます。



ディレクトリ/ var / mobile / Applications /内にアプリケーションをインストールすると、「サンドボックス」として機能するディレクトリが作成されます。 アプリケーションのほとんどすべての可能なアクションは、そのスコープによって制限されます。 NSUserDefaultsチンキ、その他のplistファイル、Cookie、およびユーザーが変更できるデータベースやその他のリソースが保存される場所です。 このディレクトリにアクセスするには、デバイスに脱獄をインストールしないでください。これは、任意のファイルマネージャー( iFunBoxなど )を使用して可能です。



この脆弱性のpre延を説明するために、有料のApp Storeで絶え間なく点滅するアプリケーション、 Smart Safeを取り上げます。



iFunBoxを使用して、 / Documentsフォルダーの内容に慣れます。 とりわけ、 notes.sqlitenotes.sqlite-shmnotes.sqlite-walのファイルが含まれています。 notes.sqliteデータベースには3つのテーブルが含まれています。



特に興味深いのは、それらの最初のものです。 ZDATEフィールドには、出版日がZBODY-ノートのテキスト、 ZTITLE-タイトルに含まれています。 すべてのテキストは暗号化されず、クリアテキストで保存されます。







免責事項
開発者には脆弱性が通知されましたが、コメントや修正は行われませんでした。 前述の脆弱性は、唯一のものではありません;アプリケーションは、すべてのデータを完全にオープンな形式で保存します。



この脆弱性に対処する1つの方法は、オンザフライで透過的な暗号化をサポートするSQLCipherフレームワークを使用することです。 すべての暗号化機能(AES256、擬似乱数ジェネレーター、PBKDF2キー)で、SQLCipherはOpenSSLライブラリを使用します 。 詳細な説明、ドキュメント、およびアセンブリは、このリンクにあります。



この記事では、CocoaでSQLiteデータベースを操作するための一般的なラッパーであるFMDatabaseとともにSQLCipherを使用する方法について説明します。



Cocoapodsを使用する場合、FMDatabaseとSQLCipherをプロジェクトに追加するには、 ポッドファイルにポッドライン「FMDB / SQLCipher」を追加するだけです。 AppDelegate.m参照してください



- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentDir = [documentPaths objectAtIndex:0]; self.databasePath = [documentDir stringByAppendingPathComponent:@"sqmple.sqlite"]; [self createAndCheckDatabase]; return YES; } -(void) createAndCheckDatabase { BOOL success; NSFileManager *fileManager = [NSFileManager defaultManager]; success = [fileManager fileExistsAtPath:self.databasePath]; if (success) return; // If file exists, don't do anything // if file does not exist, make a copy of the one in the Resources folder NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"sample.sqlite"]; // File path [fileManager copyItemAtPath:databasePathFromApp toPath:self.databasePath error:nil]; // Make a copy of the file in the Documents folder // Set the new encrypted database path to be in the Documents Folder NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentDir = [documentPaths objectAtIndex:0]; NSString *encryptedDatabasePath = [documentDir stringByAppendingPathComponent:@"encrypted.sqlite"]; NSString *key = @"PassKey"; // SQL Query. NOTE THAT DATABASE IS THE FULL PATH NOT ONLY THE NAME const char* sqlQ = [[NSString stringWithFormat:@"ATTACH DATABASE '%@' AS encrypted KEY '%@';", encryptedDatabasePath, key] UTF8String]; sqlite3 *unencrypted_DB; if (sqlite3_open([self.databasePath UTF8String], &unencrypted_DB) == SQLITE_OK) { // Attach empty encrypted database to unencrypted database sqlite3_exec(unencrypted_DB, sqlQ, NULL, NULL, NULL); // export database sqlite3_exec(unencrypted_DB, "SELECT sqlcipher_export('encrypted');", NULL, NULL, NULL); // Detach encrypted database sqlite3_exec(unencrypted_DB, "DETACH DATABASE encrypted;", NULL, NULL, NULL); sqlite3_close(unencrypted_DB); } else { sqlite3_close(unencrypted_DB); NSAssert1(NO, @"Failed to open database with message '%s'.", sqlite3_errmsg(unencrypted_DB)); } self.databasePath = [documentDir stringByAppendingPathComponent:@"encrypted.sqlite"]; }
      
      





それだけで、暗号化されたデータベースが作成され、作業を開始できます。 データベースを開くためのメソッドを書きましょう:



 - (FMDatabase *)openWriteableDatabase { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"encrypted.sqlite"]; FMDatabase* database = [FMDatabase databaseWithPath:writableDBPath]; [database open]; NSString *key = @"PassKey"; [database setKey:key]; return database; }
      
      





この方法でデータベースを開くと、行の追加、削除など、あらゆるアクションを実行できます。 もちろん、暗号化されたデータベースを使用する場合、アプリケーションコードに配線された静的キーを使用することはお勧めしません。 代替案としては、各デバイスに固有のキーを動的に生成する方法を開発することです(このため、 identifierForVendorやユーザー設定パスワードなどのさまざまなパラメーターの組み合わせを使用して、アプリケーションにアクセスできます)。 データベースで使用されるキーの変更は、他の何かと同じくらい簡単です:



 NSString *newKey = @"NewPassKey"; [database rekey:newKey];
      
      





キー生成の基になるパラメーターの1つが動的である場合、その変更に応じてこのメソッドを呼び出すことを忘れないでください。



もちろん、SQLCipherを使用してもユーザーデータを完全に保護することはできませんが、初心者の研究者を怖がらせ、経験豊富なクラッカーの生活を複雑にします。 最後に、このフレームワークを使用するアプリケーションがApp Storeに表示されるために は、この投稿で JacobLによって詳しく説明されているERNフォームを取得する必要があるという事実に言及する価値があります。



All Articles