Androidにおけるセキュリティ設計と動作(後編)

※この記事は、書籍『Android Security 安全なアプリケーションを作成するために』の第3章の内容を、ThinkIT向けに特別にオンラインで公開しているものです。詳しくは記事末尾の書籍紹介欄をご覧ください。今回は、前回の「第3回 Androidにおけるセキュリティ設計と動作(前編)」に続

タオソフトウェア株式会社

2012年3月9日 20:00

※この記事は、書籍『Android Security 安全なアプリケーションを作成するために』の第3章の内容を、ThinkIT向けに特別にオンラインで公開しているものです。詳しくは記事末尾の書籍紹介欄をご覧ください。

今回は、前回の「第3回 Androidにおけるセキュリティ設計と動作(前編)」に続いて、アンドロイドのセキュリティ関連の設計と動作について技術的な観点から見ていきます。

3.5 固有識別子

多くのWebアプリケーションでは、ユーザがログインIDとパスワードを入力してサーバにログインし、そのユーザのデータにアクセスします。ユーザがアカウントを作成したり、入力ボックスにパスワードを入力したりするのは非常に手間がかかります。このためWebの世界では、Cookieを利用することで、実際にはログインしていなくてもログインしているかのように扱うケースがあります。たとえばAmazonでは、過去の履歴情報をCookieに保存することで、Cookieの情報に基づいてユーザを識別し、ユーザに表示する画面を変更しています。ユーザが実際にログインするのは商品を購入する段階になったときです。このようにセキュアにする必要がある部分でのみログインを要求することで、ユーザの利便性を向上させているのです。

サーバ側でユーザを区別したいが、ユーザにとってアカウントを作成する必然性がない、という場合は、プログラム上で何らかの重複しないグローバル識別子を作成する必要があります。

本節では、この一意な識別子について見ていきます。

3.5.1 識別子の生成

代表的な例は、UUID(Universally Unique Identifier)を生成することです。

リスト3-4 UUIDの生成例※2

public class Installation {
  private static String sID = null;
  private static final String INSTALLATION = "INSTALLATION";
 
  public synchronized static String id(Context context) {
    if (sID == null) {
      File installation = new File(context.getFilesDir(), INSTALLATION);
      try {
        if (!installation.exists())
          writeInstallationFile(installation);
        sID = readInstallationFile(installation);
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    }
    return sID;
  }
 
  private static String readInstallationFile(File installation) throws IOException {
    RandomAccessFile f = new RandomAccessFile(installation, "r");
    byte[] bytes = new byte[(int) f.length()];
    f.readFully(bytes);
    f.close();
    return new String(bytes);
  }
 
  private static void writeInstallationFile(File installation) throws IOException {
    FileOutputStream out = new FileOutputStream(installation);
    String id = UUID.randomUUID().toString();
    out.write(id.getBytes());
    out.close();
  }
}

※2 参照:Android Developers Blog「Identifying App Installations」

アプリケーションが最初に実行されるときに、上記のようなコードを使ってUUIDを生成し、ファイルに保存します。次回以降は、アプリケーションの起動時にこのファイルからUUIDを取り出すことで、アプリケーションがアンインストールされるまで同じIDを使用できます。アプリケーションを一度アンインストールしてから再度インストールした場合、最初のIDとは異なるIDが生成されますが、IDの値が変化しても通常は問題ありません。問題となる場合は、一般に、ユーザIDとパスワードによる認証を行う必要があるでしょう。

リスト3-4はアンドロイド上でUUIDを生成する例ですが、サーバ側で生成したUUIDを使用することもできます。

3.5.2 ハードウェアに関する識別子

IMEI
IMEI(International Mobile Equipment Identifier)は、端末識別番号です。IMEIは携帯電話固有の番号であり、生産国、メーカー名などの組み合わせによる15桁の数字で構成されています。
IMEIを取得するには、READ_PHONE_STATEパーミッションが必要です。

リスト3-5 IMEIの取得例

TelephonyManager telephonyManager =
  (TelephonyManager)getSystemService(TELEPHONY_SERVICE);

// GSMのIMEIにはREAD_PHONE_STATEが必要
String deviceId = telephonyManager.getDeviceId();
Log.v(TAG, "deviceId(IMEI)=" + deviceId);

// GSMのIMEI/SVにはREAD_PHONE_STATEが必要
String deviceSoftwareVersion = telephonyManager.getDeviceSoftwareVersion();
Log.v(TAG, "deviceSoftwareVersion(IMEI/SV)=" + deviceSoftwareVersion);

リスト3-6 出力例※3

10-24 14:20:53.173: V/Activity(11558): deviceId(IMEI)=254049043147024
10-24 14:20:53.173: V/Activity(11558): deviceSoftwareVersion(IMEI/SV)=00

IMEIをユーザと紐付けすることは、以下の理由により、あまり意味を持ちません。

  • ユーザが新しい携帯電話に変えるとIMEIが変化する。
  • 同じユーザが携帯電話を2つ持っていることがある。
  • 携帯電話が中古品として販売され、他のユーザが使用することがある。

また、IMEIは携帯電話に付加される番号です。アンドロイドOSは携帯電話だけでなく、フォトフレーム、データ通信契約が必要ないタブレット、その他さまざまなデバイスで動いています。こうした携帯電話ではないデバイスでIMEIを取得すると、固定値が返されたり、値がなかったりします。また、端末によってはバグがあり、ゼロやアスタリスク(*)を返すこともあります。

さらに、IMEIを取得するには、READ_PHONE_STATEパーミッションが必要です。このパーミッションは電話番号の取得も可能にするパーミッションです。作成するアプリケーションが通信を行い、かつREAD_PHONE_STATEパーミッションがある場合は、電話番号をサーバに送って収集していると疑われる可能性があります。

IMEIを取得するかどうかについては、十分に検討した上で決定してください。

※3 これ以降、出力例に表示されている値は一部変更を加えています。

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored

ClickHouse Cloudが実現した広告運用SaaS「ATOM」のデータ基盤革新、パフォーマンスを向上しながら、運用負荷とコストを削減 11月11日 6:20 AIで開発が加速する時代、品質保証はどう変わる? Tricentisが示すAIエージェント活用の実像 11月9日 6:45 悪用までの猶予が「1分」に迫るフロンティアAI時代に開発と本番を貫く脆弱性管理が必要 10月29日 8:30 欧州CRA対応とSBOM運用。AI生成コードのOSS混入問題の対策とは ――スニペット単位で検出する「FossID」「Insignary Clarity」によるSBOM運用 9月16日 6:40 PostgreSQLからTiDBへ、稼働中SaaSで進める段階的DB移行の実践と再設計への展望 9月7日 6:30 機能安全開発におけるGoogleTestの活用を支援!「Parasoft C/C++test CT」で実現する効率化&AI連携 4月14日 6:30 【CNDW2025】Grafanaが明かす「オブザーバビリティの哲学」ー最小限の労力で実用的なインサイトを得るには 1月23日 6:30 【CNDW2025】プロダクト急増に備える基盤刷新 ーウェルスナビがECSからEKSへの移行で得た知見とは 1月15日 6:30 【CNDW2025】250環境を5人で運用、構築時間は30分に ーKINTOテクノロジーズが語るインフラ基盤組織の作り方 2025年12月18日 6:30 新たな自動化で熱視線! AIエージェントの「推論能力」を支える2つのコンポーネントとは? 2025年11月28日 6:30