前回の記事では単純にAPKファイルを作成し、その中からアプリケーションキーやクライアントキーが見つけられるのを確認しました。今回から、その隠蔽方法について解説していきます。
まず初回は(といっても一番正解に思えます)C++を使って隠蔽する方法です。
Androidプロジェクトを作る
C++に対応するため、Androidプロジェクトを作成する際にNative C++を選択します。
言語はKotlinで問題ありません。
native-lib.cppの編集
app/cpp
ディレクトリにnative-lib.cppというファイルがありますので、これを編集します。
今回はアプリケーションキーとクライアントキーを返却する関数を追加します。 YOUR_APPLICATION_KEY
と YOUR_CLIENT_KEY
はそれぞれ書き換えてください。
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_kotlinhiddenkey_MainActivity_applicationKey(
JNIEnv* env,
jobject /* this */) {
std::string hello = "YOUR_APPLICATION_KEY";
return env->NewStringUTF(hello.c_str());
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_kotlinhiddenkey_MainActivity_clientKey(
JNIEnv* env,
jobject /* this */) {
std::string hello = "YOUR_CLIENT_KEY";
return env->NewStringUTF(hello.c_str());
}
これで関数の追加が完了です。
Android SDKを導入する
次にNCMBのAndroid SDKを導入します。これはイントロダクション (Android) : クイックスタート | ニフクラ mobile backendに沿って進めてもらえば問題ありません。具体的には次の手順を行います。
- GitHubのリリースページからSDKをダウンロードして展開
- NCMB.jarをapp/libsディレクトリに入れる
- app/build.gradle の編集
- app/src/main/AndroidManifest.xml の編集
コードを修正する
MainActivity.kt を修正します。まずSDKを読み込みます。
import com.nifcloud.mbaas.core.NCMB;
次にC++ファイルで設定した関数を定義します。
class MainActivity : AppCompatActivity() {
// 省略
external fun applicationKey(): String
external fun clientKey(): String
}
そしてNCMBの初期化時に呼び出します。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
NCMB.initialize(this.getApplicationContext(),applicationKey(),clientKey());
// 省略
}
これで完了です。
実行する
初期化が終われば、後は普段のNCMB利用と同じく使えます。
// クラスのNCMBObjectを作成
val obj = NCMBObject("TestClass")
// オブジェクトの値を設定
try {
obj.put("message", "Hello, NCMB!")
} catch (e: NCMBException) {
e.printStackTrace()
}
// データストアへの登録
obj.saveInBackground { e ->
if (e != null) {
//保存に失敗した場合の処理
Log.d("Main", "Data creates failed.");
} else {
//保存に成功した場合の処理
Log.d("Main", "Data creates successful.");
}
}
キーについて
jedx-guiを使って見ても、関数を呼んでいるだけです。
アプリをビルドしてAPKファイルを作り、それをZipファイルとして展開すると、libxxxx.so
のようなファイルの存在を確認できます。
これはアーキテクチャごとに作成されます。このファイルはC++の共有ライブラリになります。このファイルを逆コンパイルしてみましたが、アプリケーションキーやクライアントキーとおぼしき部分は見当たりませんでした(反転している部分がapplicationKey関数の該当とおぼしき部分)。
HEXエディタを使った場合
今回は単純な文字列を返すだけにしたので、HEXエディタで検索するとキーを発見できます。
あらかじめキーをエンコードしておいて、C++からデコードして返すようにしたり、文字を分割したりすると発見しづらくなりそうです。
まとめ
アプリケーションキーやクライアントキーを確実に隠蔽化する場合には、C++プロジェクトとしてAndroidアプリを開発するのが一番かと思います。キーの取得だけをC++の関数としていますので、他のコードはKotlinが使えるので、生産性は変わらないでしょう。お試しください。