Шифрование файла базы данных SQLite в iPhone OS - PullRequest
20 голосов
/ 30 мая 2009

Любая база данных SQLite на iPhone - это просто файл, связанный с приложением. Для любого относительно просто извлечь этот файл и запросить его.

Каковы ваши предложения по шифрованию файла или данных, хранящихся в базе данных.

Редактировать: Приложение - игра, в которую будут играть против других пользователей. Информация о сильных и слабых сторонах пользователей будет храниться в БД. Я не хочу, чтобы пользователь мог взломать телефон, поднять свою репутацию / силу и т. Д., А затем выиграть турнир / лигу и т. Д. (NB: пытаться быть расплывчатым, поскольку идея подпадает под NDA).

Мне не нужно военное шифрование, я просто не хочу хранить вещи в виде простого текста.

Редактировать 2: Еще немного уточнения, мои главные цели:

  1. Сделать взлом конфиденциальных данных нетривиальным
  2. Иметь простой способ обнаружить, были ли данные изменены (какая-то контрольная сумма)

Ответы [ 8 ]

18 голосов
/ 03 июня 2009

Вы не можете доверять клиенту, точка. Если ваше автономное приложение может его расшифровать, то и они тоже. Либо поместите данные на сервер, либо не беспокойтесь, так как количество людей, которые действительно взломают их для улучшения статистики, будет крошечным, и, вероятно, их все равно следует вознаградить за усилия!

Поместите в базу данных строку с надписью "пожалуйста, не обманывайте".

12 голосов
/ 02 июня 2009

Здесь есть как минимум два более простых подхода (оба дополняют друг друга), которые позволяют избежать шифрования значений или баз данных в памяти:

# 1 - обнаружение трещин ipa

Избегайте технических (и юридических) хлопот по шифрованию базы данных и / или содержимого и просто определите, является ли приложение пиратским, и отключите сетевые / оценочные / рейтинговые аспекты игры. Для получения более подробной информации см. Следующее:

http://thwart -ipa-cracks.blogspot.com / 2008/11 / detection.html

# 2 - проверка целостности данных

В качестве альтернативы можно сохранить HMAC / соленый хеш важных столбцов в каждой строке при сохранении ваших данных (и в вашей исходной базе данных sqlite). При загрузке каждой строки сверяйте данные с HMAC / хэшем, и, если проверка не удалась, действуйте соответствующим образом.

Ни один из этих подходов не заставит вас заполнять формы экспорта шифрования, требуемые Apple / правительством США.

Представление баллов

Не забывайте, что вам нужно сделать что-то похожее для фактических представлений, чтобы защитить их от значений, отличных от вашего приложения. Вы можете увидеть реализацию этого в каркасах cocos2d-iphone и cocoslive в http://code.google.com/p/cocos2d-iphone/ и http://code.google.com/p/cocoslive/

Ответ на комментарии

Здесь нет решения, которое на 100% предотвратит подделку данных. Если это требование, клиент должен быть только для просмотра, а все состояние и логика должны быть рассчитаны на доверенном сервере. В зависимости от приложения клиенту потребуются дополнительные анти-чит-механизмы.

Существует множество книг по разработке массовых многопользовательских игр, в которых обсуждаются эти проблемы.

Использование хеша с известным секретом в коде, вероятно, является разумным подходом (по крайней мере, при рассмотрении типа приложений, которые обычно существуют в App Store).

11 голосов
/ 29 июня 2009

Как сказал Кендалл, ключ к устройству в основном просит взломать. Однако есть люди, у которых есть причины запутывать данные с помощью ключа на устройстве. Если вы полны решимости сделать это, вы можете использовать SQLCipher для своей реализации. Это сборка SQLite, которая обеспечивает прозрачное шифрование на уровне страницы всей БД. В Mobile Orchard есть учебник по для его использования в приложениях для iPhone.

5 голосов
/ 30 мая 2009

Как вы думаете, насколько вероятно, что ваш обычный пользователь будет делать это? Я предполагаю, что вы проходите через магазин приложений, что означает, что все подписано / зашифровано перед тем, как попасть на устройство пользователя. Им придется сделать джейлбрейк своего устройства, чтобы получить доступ к вашей базе данных.

Какие данные вы храните так, что они нуждаются в шифровании? Если он содержит пароли, введенные пользователем, вам не нужно их шифровать; пользователю не нужно будет узнавать свой пароль. Если это общие данные больших двоичных объектов, к которым пользователь должен обращаться только через приложение, это может быть так же просто, как хранить зашифрованные большие двоичные объекты с помощью API безопасности .

.

Если вы хотите защитить всю базу данных, вы все равно захотите использовать API безопасности, но вместо этого для всего файла, и расшифровать файл по мере необходимости, прежде чем открывать его. Проблема здесь в том, что если приложение закрывается без очистки, у вас остается расшифрованный файл.

Возможно, вы захотите взглянуть на резидентные базы данных или временные базы данных, которые вы можете создать с помощью шаблона db или жестко заданной схемы в программе (посмотрите документацию для sqlite3_open ). Данные можно расшифровать, вставить во временную базу данных, а затем удалить дешифрованную базу данных. Сделайте это в обратном направлении при закрытии соединения.

Редактировать

Вы можете создать свою собственную схему шифрования, я уверен, с помощью очень простой системы безопасности, XOR-данные, хранящиеся в приложении, и хранить хэш где-то еще, чтобы убедиться, что он не изменяется или что-то в этом роде.

3 голосов
/ 13 июня 2014

SQLCipher:

Исходя из моего опыта, SQLCipher - лучший вариант для шифрования базы данных.

Как только ключ («ключ PRAGMA») установлен, SQLCipher автоматически зашифрует все данные в базе данных! Обратите внимание, что если вы не установите ключ, то SQLCipher будет работать идентично стандартной базе данных SQLite.

Вызов sqlite3_key или «PRAGMA key» должен произойти как первая операция после открытия базы данных. В большинстве случаев SQLCipher использует PBKDF2, функцию получения соленых и повторяющихся ключей для получения ключа шифрования. Альтернативно, приложение может сказать SQLCipher использовать определенный двоичный ключ в нотации BLOB-объектов (обратите внимание, что SQLCipher требует ровно 256 бит материала ключа), т.е.

enter image description here

Справка:

http://sqlcipher.net/ios-tutorial

Я надеюсь, что кто-то сэкономит время на изучение этого вопроса

2 голосов
/ 04 июня 2009

Игнорируя философские и экспортные проблемы, я бы посоветовал вам лучше зашифровать данные в таблице напрямую.

Вам необходимо скрыть ключи дешифрования в вашем коде. Как правило, это означает разбивать их на части и кодировать строки в шестнадцатеричном формате и использовать функции для сборки частей ключа.

Для этого алгоритма я бы использовал надежную реализацию AES для любого языка, который вы используете. Может быть, это для C #:

http://msdn.microsoft.com/en-us/magazine/cc164055.aspx

Наконец, вам нужно знать об ограничениях подхода. А именно, ключ дешифрования является слабым звеном, он будет доступен в памяти во время выполнения в виде открытого текста. (Как минимум) Это должно быть так, чтобы вы могли использовать его. Внедрение вашей схемы шифрования является еще одним недостатком - любые недостатки также содержат недостатки в вашем коде. Как отметили несколько других людей, ваши клиент-серверные связи также подозрительны.

Вы должны помнить, что ваш исполняемый файл может быть проверен в шестнадцатеричном редакторе, где строки открытого текста выпрыгнут из случайного мусора, который является вашим скомпилированным кодом. И что многие языки (например, C #) могут быть скомпилированы в обратном порядке, и все, что будет отсутствовать - это комментарии.

Все это говорит о том, что шифрование ваших данных немного поднимет планку обмана. Как много зависит от того, насколько вы осторожны; но даже в этом случае решительный противник все еще сломает ваше шифрование и обман. Кроме того, они, вероятно, напишут инструмент, который облегчит вашу игру; оставив вам сценарий гонки вооружений на этом этапе.


Что касается значения контрольной суммы, вы можете вычислить контрольную сумму на основе суммы значений в строке, предполагая, что в вашей базе данных достаточно числовых значений для этого. Или, для множества логических значений, вы можете сохранить их в поле varbinary и использовать побитовый исключительный оператор ^ для их сравнения - вы должны получить 0s.

Например,

для числовых столбцов,

2 | 3 | 5 | 7 | со столбцом контрольной суммы | 17 |

для логических значений,

0 | 1 | 0 | 1 | со столбцом контрольной суммы | 0101 |

Если вы сделаете это, вы даже можете добавить итоговую строку в конце, которая суммирует ваши контрольные суммы. Хотя это может быть проблематично, если вы постоянно добавляете новые записи. Вы также можете конвертировать строки в их компоненты ANSI / UNICODE и суммировать их тоже.

Затем, когда вы хотите проверить контрольную сумму, просто сделайте выбор следующим образом:

Select * 
FROM OrigTable 
right outer join 
(select pk, (col1 + col2 + col3) as OnTheFlyChecksum, PreComputedChecksum from OrigTable) OT on OrigTable.pk = OT.pk
where OT.OnTheFlyChecksum = OT.PreComputedChecksum
1 голос
/ 08 июня 2009

Кажется, что проще всего синхронизировать все результаты турнира со всеми iPhone в турнире. Вы можете сделать это во время каждой игры: перед игрой, если базы данных двух телефонов противоречат друг другу, отображается предупреждение.

Если пользователь A фальсифицирует результат, если его игра с пользователем B, будет распространяться до тех пор, пока B не увидит его с предупреждением о том, что данные A не совпадают с его телефоном. Затем он может пойти и избить объяснить А, что его поведение не так, как в реальной жизни, если кто-то обманывает.

Когда вы вычисляете окончательные результаты турнира, показывайте предупреждение, называйте имена и выбрасывайте все игры с противоречивыми результатами. Это устраняет стимул к мошенничеству.

Как уже говорилось, шифрование не решит проблему, поскольку вы не можете доверять клиенту. Даже если ваш обычный человек не может использовать дизассемблер, все, что требуется, - это один мотивированный человек, и любое ваше шифрование будет взломано.

0 голосов
/ 07 января 2010

Тем не менее, если на платформе Windows вы также можете выбрать SQLiteEncrypt , чтобы удовлетворить ваши потребности. SQLiteEncrypt расширяет поддержку шифрования sqlite, но вы можете рассматривать его как оригинальную библиотеку sqlite3 c.

...