不正改造アプリ対策のための署名認証セキュリティ強化とは

コラム概要

■こんな方におすすめ:

  • Androidの単純なアプリを作成できる(理解できる)
  • アプリのセキュリティについて少し踏み込んだ内容を知りたい
  • 開発/技術担当の方

■難易度:★★☆

■ポイント:

  • アプリ開発の際、署名認証を施すことで、一定の堅牢化効果がある
  • しかし、クラッカーの技量が上がると署名認証によるセキュリティ対策が
  • 無効化となる可能性がある
  • 署名認証等のセキュリティ対策のリスク管理もセキュリティ強化策として
  • 必要不可欠である

1.はじめに

アプリを開発する際、セキュリティ対策の1つである署名認証を施すことで、
一定の堅牢化効果はありますが、不正改造アプリの製作者(クラッカー)の技量が上がると、署名認証が回避され、
アプリを保護できなくなることがあります。このコラムでは、こうした攻撃を防ぐためのより強固な対策について解説します。

本題に入る前に、ここで使用する特に重要な言葉について簡単に説明します。

  • 署名
     署名の機能:-アプリに個人や企業の情報を埋め込み、アプリの配信元を保証する
          -アプリの内容が署名時から改変がないことを保証する
     アプリをインストールするには署名が必須となります。
     アプリインストール時にOSが署名の情報を用いてアプリの内容に改ざんがないか整合性をチェックするためです。
  • キーストア
     署名に必要な鍵のようなものです。
    (これを紛失すると、基本的にアプリのアップデートは出来なくなります。)
  • 署名のユニーク性
    キーストアには、署名のユニーク性(一意性)を保証するための値(fingerprint)が埋め込まれています。
    これにより、正規のアプリか、改ざんされた不正改造アプリかを区別します。キーストア作成時に入力する個人・企業の情報が同一であっても、値(fingerprint)が異なっていれば、別の署名として認識します。

※キーストアの作成時に、入力する情報例:

  • 会社名(組織名)
  • 住所
  • 国 等…

2.不正改造アプリについて

まず、不正改造アプリについて具体的に説明していきます。
クラッカーがアプリのチート機能等を付与するような改ざん行為があり、それをここでは不正改造アプリと呼びます。

※クラッカーの改ざんの狙いは、以下の例が挙げられます。
・課金ルートの回避
・アプリにチート機能を付与したものを販売し不当な利益を得ること
・マルウェア等を仕込んだ不正改造アプリを販売し、購入したユーザーの情報を盗み取ること
・自己技術の誇示

正規アプリを改ざんして作成した不正改造アプリは、配信する際の正規(元)の署名の状態ではアプリの内容の整合性がとれなくなるため、再度署名をする必要があります。
しかし、クラッカーは正規アプリのキーストアを所持していないため、クラッカーが用意した別のキーストアで署名をすることになります。

3.署名認証の対策とその効果

不正改造アプリとしての動作を防ぐために、予め正規の署名の情報をアプリ内に保存しておきます。
その署名と実際のアプリの署名を起動時に比較するという、署名認証を実装できます。

[実装例]

4.セキュリティの限界

しかし、上記のような実装の署名認証はセキュリティ強度に限界があります。

どういうことかと言うと、簡単な署名認証では、不正改造アプリの作成を確実に防ぐことはできません。
というのも、クラッキングテクニックの一つであるパッチ(ある任意の部分の命令語を無効命令語等で上書き・書き換え)を用いると、認証を回避でき、更に認証を無効化にした不正改造アプリが作成できます。

上記の不正改造アプリでは署名認証が回避・無効化されているため、アプリは署名認証が機能することなく動作します。

5.難読化の限界

Java・kotlin(dex)のセキュリティと言えば、R8・ProGuardのような難読化ツールを思い浮かべる方もいるのではないでしょうか?

難読化は、自身で実装したメソッドの名前を隠蔽する効果があります。
例えば今回のケースだと、checkSignのメソッド名が隠蔽されます。

しかし、今回の署名認証には脆弱性が残ります。なぜなら、署名認証では、外部メソッドや外部変数が重要な役割を果たしていますが、その外部メソッドや外部変数は、難読化の対象外になっているためです。

そのため、クラッカーは、難読化の対象外のgetPackageInfoのようなメソッドを目星として認証部分を短時間で特定しパッチによる署名認証を無効化することが、可能になるという訳です。
つまり、難読化だけでは、セキュリティ強度に限界があると言えます。

6.強度の高い署名認証のためにすべきこと

では、どのようなセキュリティ対策を難読化に加えて施せばいいでしょうか。今回は3つの方法をご紹介します。

1.十分な数の署名認証コードをアプリに実装する
1つ目は、署名認証コード(全く同じでないことが望ましい)を複数実装する方法です。
この方法を施すことで、クラッカーはそれぞれのコードに適切なパッチを当てる部分を特定する作業が発生します。
そのため、十分な数の署名認証コードがアプリに実装されていると、クラッカーがパッチを当てることを諦めることが期待できます。

2.署名認証コードをオリジナルで実装する
2つ目は、外部メソッドを独自の方法で実装する方法です。
例えば、PackageManager.GET_SIGNATURESやpackageInfo.signaturesというような
クラッカーの目を引く外部メソッドや外部変数を直接使用するのではなく、より複雑な構成のものをオリジナルで実装することです。この方法により、クラッカーがパッチを当てる箇所を隠蔽することができます。

3.署名認証をサーバ側で実施する
最後は、アプリ起動時等に取得した署名をサーバ側に送信し、サーバ側で認証する方法です。
署名認証には、「アプリの署名の取得」⇒「署名認証」というステップが必要です。
その過程においてクラッカーが簡単なパッチで出来ることは、「署名認証」を無かったことにする方法で、「アプリの署名を取得」を偽装することはできません。したがって、「署名認証」の部分をサーバ側で実施するようにすると、クラッカーが作成した署名がサーバ側に送信されるため、不正改造アプリの使用者を検出することができます。

7.更なる認証の強化

弊社のCrackProofという製品を使用することにより、簡単にクラッキングしにくい署名認証の機能を付与できます。

不正改造アプリを防ぐには署名認証以外にも考慮する点があります。
それらについてもCrackProofを使用することにより、不正改造アプリの作成の難易度を飛躍的に高めることができます。お困りの場合はぜひ、ご連絡ください。