SQLite の暗号化
Akihiro Matsuura @ Syuhari, Inc.
About me
• 松浦 晃洋
• 株式会社シュハリ 代表取締役
• Cocos2d-x ゲーム開発
• 書籍、雑誌などの執筆
• Cocos2d-x エヴァンジェリスト
普段はこんなアプリ
作ってます
Cocos2d-JS の翻訳本
Cocos2d-x Game
Development Essentials
Building Android Games 

with Cocos2d-x
海外での出版に協力
Cocos2d-x Cookbook
https://www.packtpub.com/game-development/cocos2d-x-cookbook
http://www.amazon.co.jp/dp/B013R02BMY/
2015年12月3日
発売予定
予約受付中!
SQLite を暗号化する
候補は2つ
SQLCipher
iOS でビルド OK

Android でビルド NG

SQLiteManager が対応している
wxSqlite3
C++ ライブラリでビルドも簡単
wxSqlite3 を
Cocos2d-x へ組み込む
wxSqlite3 をダウンロード
• ドキュメント
• http://wxcode.sourceforge.net/docs/wxsqlite3/

• ダウンロード
• http://sourceforge.net/projects/wxcode/files/Components/
wxSQLite3/

• 検証は Cocos2d-x ver3.6、wxSqlite3 ver3.1.1 で行いました

Cocos2d-x ver3.2 でも動作確認しました
wxSqlite を Cocos2d-x へコピー
zip内の sqlite3/secure/src を 

cocos2d/external/wxsqlite/src へコピー
iOS 用の設定
Xcode にソースを追加
wxsqlite/src 内の 

sqlite3.h 

sqlite3secure.c  
フラグを追加
Other C Flags に -DSQLITE_HAS_CODEC を追加する
#ifdef SQLITE_HAS_CODEC
/*
** Specify the key for an encrypted database. This routine should be
** called right after sqlite3_open().
**
** The code to implement this API is not available in the public release
** of SQLite.
*/
SQLITE_API int sqlite3_key(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The key */
);
SQLITE_API int sqlite3_key_v2(
sqlite3 *db, /* Database to be rekeyed */
const char *zDbName, /* Name of the database */
const void *pKey, int nKey /* The key */
);
SQLITE_HAS_CODEC を定義することにより、

sqlite3_key や sqlite3_rkey が使えるようになる
sqlite3.h
Android 用の設定
cocos2d/external/wxsqlite/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := wxsqlite3_static
LOCAL_MODULE_FILENAME := libwxsqlite3
LOCAL_CFLAGS += -DSQLITE_HAS_CODEC
LOCAL_SRC_FILES := src/sqlite3secure.c
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/src
LOCAL_C_INCLUDES := $(LOCAL_PATH)/src
include $(BUILD_STATIC_LIBRARY)
(新規作成)
• 赤文字は削除
• 青文字は修正
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := cocos_localstorage_static
LOCAL_MODULE_FILENAME := liblocalstorage
LOCAL_SRC_FILES := LocalStorage.cpp 
LocalStorageAndroid.cpp
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/..
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../..
LOCAL_CFLAGS += -Wno-psabi
LOCAL_CFLAGS += -DSQLITE_HAS_CODEC
LOCAL_EXPORT_CFLAGS += -Wno-psabi
LOCAL_WHOLE_STATIC_LIBRARIES := wxsqlite3_static
LOCAL_STATIC_LIBRARIES := cocos2dx_internal_static
include $(BUILD_STATIC_LIBRARY)
$(call import-module,.)
$(call import-module,external/wxsqlite3)
cocos2d/cocos/storage/local-storage/Android.mk
cocos2d/cocos/storage/local-storage/
LocalStorage.cpp
#include "LocalStorage.h"
#include "platform/CCPlatformMacros.h"
//#if (CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID)
#include <stdio.h>
#include <stdlib.h>
L 33 と L157 をコメントアウトする
proj.android/jni/Android.mk
LOCAL_SRC_FILES := hellocpp/main.cpp 
../../Classes/AppDelegate.cpp 
../../Classes/HelloWorldScene.cpp 
../../cocos2d/external/wxsqlite/src/sqlite3secure.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../cocos2d/external/wxsqlite/src/
LOCAL_CFLAGS += -DSQLITE_HAS_CODEC
実際に使ってみる
DBへのアクセス方法
sqlite3_open(path.c_str(), &database);
DB オープン後にパスワードを指定するだけ
sqlite3_key(database, password, (int)strlen(password));
注意点
• 初回起動時に空の DB を作成して暗号化すること
• SQLite のファイルをコピーしてきて暗号化するこ
とはできない
• SQL の更新が面倒
• 暗号化されるとデバッグしにくいので暗号化は仕上げの段階で行う方
がいい
• ただ暗号化後のパフォーマンスチェックは大事
• 普段は暗号化せずにリリースビルドとチェック時のみに暗号化する
• パフォーマンスは若干低下
• 頻繁なアクセスは出来るだけしないようにする
実際に使ってみて
• SQL の更新が面倒
• 暗号化する、しないを簡単にかつ確実に行いたい
問題点
結構変更あるし、DB にデータ挿入してるし
SQL 作るのが面倒
問題点1:DB の更新が面倒
SQLite ファイルからビルド時に自動的に SQL
をダンプするスクリプトを作成
SQLite をダンプするスクリプト
#!/bin/sh
commandline()
{
sleep 1; echo ".output ../Resources/data/data.sql"
sleep 1; echo ".dump"
sleep 1; echo ".exit"
}
commandline | sqlite3 ../Resources/data/data.sqlite
Xcode の Pre-action に設定
SQL を読み込み暗号化した

データベースを作成
sqlite3 *database = NULL;
sqlite3_open(dbpath.c_str(), &database);
sqlite3_key(database, DB_PASSPHRASE, (int)strlen(DB_PASSPHRASE));
auto util = FileUtils::getInstance();
std::string path = util->fullPathForFilename(“path/to/sql”);
std::string sql = util->getStringFromFile(path);
sqlite3_exec(database, (char*)sql, 0, 0, NULL);
sqlite3_close(database);
問題点2:暗号化する設定を変える
#if !defined(COCOS2D_DEBUG) ||
COCOS2D_DEBUG == 0 ||
SQLITE_ENCRYPT==1
sqlite3_key(database,
DB_PASSPHRASE, (int)strlen(DB_PASSPHRASE));
#endif
COCOS2D_DEBUG >0 または
SQLITE_ENCRYPT==1 のときのみ暗号化
リリースビルドでは絶対に暗号化される
Demo
https://github.com/syuhari/wxSqlite3
Cocos2d-x で
開発したいエンジニア
大募集中!
• @syuhari
• facebook.com/syuhari

SQLite の暗号化