2012年1月26日木曜日

android:暗号化に使用するための鍵生成

android端末で、インターネット経由の通信をしたりファイルにパスワードなどを保存しておく場合、通信内容や個人情報の保護のためにデータを暗号化することが必須となる。
実際にはAESなどの方式で暗号化することになるが、暗号化/復号化で使用する鍵はどのように生成すべきか、android端末の視点から考えてみた。

暗号化鍵の生成

android端末に限らず、暗号化鍵の生成方法で候補に挙がるのはだいたい次の3パターン。
  • ソースコード内に定数として定義
  • 乱数により生成
  • 端末内の情報からパスワードを生成

それぞれの脆弱な点は以下。
  • ソースコード内に定数として定義
  • リバースエンジニアリングによりソースコードが読み取られると、簡単にパスワードが判明してしまう。 ソースコードに鍵を定義しているため、他の端末でも同じ鍵を使用する。 androidアプリなどの配布するタイプのアプリケーションでは、リバースエンジニアリングの危険性からこの方法は使用すべきではない。
  • 乱数により生成
  • アプリケーションの実行ごとにパスワードが変更されるため、次にアプリケーションを起動したときには暗号化しているデータを復号化することができない。
  • 端末内の情報からパスワードを生成
  • 使用する端末情報によっては、パーミッションが必要になり、ユーザに不要な警戒心を抱かせる。

セキュリティの面から、端末内の情報を使用すべきだろう。
パーミッションが必要な理由はインストール画面で説明するなどし、警戒を薄れさせることが必要。
にほんブログ村 IT技術ブログ Androidアプリ開発へ

2012年1月15日日曜日

android:バーコードの読み取り

androidアプリでバーコードを読み取るために、ZXingライブラリを使用することもできるが、
QRコードスキャナーというアプリを経由してバーコードを読み取ることもできる。
QRコードスキャナーの呼び出しにはインテントを使用する。

QRコードスキャナーの呼び出し

  • QRコードスキャナーをインテントで呼び出す。
  • QRコードスキャナーが端末にインストールされていなければ、AndroidMarketを起動する。

package net.kuttya.barcodescansample;

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class BarcodeScanSampleActivity extends Activity {
    // インテントリクエストコード
    private static final int REQUEST_SCAN = 0;

    private static String resultStr;
    private TextView textResult;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // 読み取り結果表示領域
        textResult = (TextView)findViewById(R.id.result);
    }

    public void clickEventScan(View v) {
        // バーコードスキャナの呼び出し
        callBarcodeScanner();
    }

    private void callBarcodeScanner() {
        Intent intentScan = new Intent("com.google.zxing.client.android.SCAN");

        try {
            startActivityForResult(intentScan, REQUEST_SCAN);
        }
        catch(ActivityNotFoundException e) {
            // バーコードスキャナが端末にインストールされていなければ、
            // AndroidMarketを起動する。
            Uri uri = Uri.parse("market://details?id=com.google.zxing.client.android");

            Intent intentMarket = new Intent(Intent.ACTION_VIEW,uri);

            try {
                startActivity(intentMarket);
            }
            catch(ActivityNotFoundException ee) {
            }
        }
    }

    @Override
    protected void onActivityResult(int request, int result, Intent intent) {
        switch(request) {
            case REQUEST_SCAN:
                if(result == Activity.RESULT_OK) {
                    resultStr = intent.getStringExtra("SCAN_RESULT");
                    textResult.setText(resultStr);
                }
                break;
            default:
                break;
        }
    }
}

  • 直接関係しないがレイアウトは次の通り

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/scan"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="clickEventScan"
        android:text="scan start" />

    <TextView
        android:id="@+id/result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

にほんブログ村 IT技術ブログ Androidアプリ開発へ

android:危険なパーミッションの組み合わせ

androidOSはOSの権限を管理するために、パーミッションという仕組みを用意している。
パーミッションは機能ごとに細かく分けられていて、アプリがなにをするかがわかるようになっている。
たとえば、 端末の電話番号を取得するアプリなら「READ_PHONE_STATE」、インターネットに接続するアプリなら「INTERNET」というパーミッションが必要となる。

パーミッションはアプリがどのような機能をもつかを示しているため、危険なアプリかどうかの判断材料のひとつとなる。
先に示した、電話番号を取得する「READ_PHONE_STATE」と、インターネットに接続する「INTERNET」のふたつのパーミッションをもつアプリの場合、端末の電話番号を使用者にわからないように外部に送信することが可能となる。

危険なパーミッションの組み合わせ

危険なパーミッションの組み合わせには、次のようなものがある。
  • インターネットに接続する「INTERNET」と端末の現在位置を取得する「ACCESS_FINE_LOCATION」
  • インターネットに接続する「INTERNET」と電話帳の内容を読み取る「READ_CONTACTS」
  • インターネットに接続する「INTERNET」とSMSの受信を取得する「READ_SMS」
  • 電話帳の内容を読み取る「READ_CONTACTS」と電話をかけることのできる「CALL_PHONE」
  • 電話帳の内容を読み取る「READ_CONTACTS」とSMSを送信できる「SEND_SMS」

危険なパーミッション組み合わせは他にも多く存在する。
androidOSにどのようなパーミッションがあるのかは、下記のサイトから確認できる。

android developers Manifest permission

アプリを使用する上で注意すべきこと

アプリがどのパーミッションを使用するか(どのような権限を持っているか)知りたい場合は、アプリをインストールした端末で確認することができる。

端末によって多少操作方法が異なるが、だいたい次の操作で確認が可能。
  1. ホーム画面でメニューボタンを押す。
  2. メニューから設定を選ぶ。
  3. 設定のリストから「アプリケーション」を選ぶ。
  4. アプリケーションのリストから「アプリケーションの管理」を選ぶ。
  5. 確認したいアプリを選ぶ。
  6. 「許可」の欄にアクセスする内容が書かれている。

また、アプリのインストール時にもパーミッションについての許可を求められるので、
危険だと判断した場合は、アプリをインストールしないようにすべき。
アプリをインストールする前に、アプリの開発元が信頼できるところなのか、アプリの紹介元は危険がないことを確認しているのかなど、他者がどのように判断したのかを確認する。
それに加え、最終的にはアプリ使用者の自己責任でアプリをインストールするようにしたい。

開発者として注意すべきこと

開発したい、または開発済みのアプリのパーミッションが危険な組み合わせとなる場合は、危険性がないことを表明しなくてはならない。使用者が不安にならないように配慮する必要がある。
androidマーケットのインストール画面で次のことをを記載すれば、多少は使用者の不安を取り除くことができる。
  • アプリで使用するパーミッションの種類を明記
  • アプリが端末情報や個人情報にアクセスする理由
  • 通話、SMS、インターネット接続など、費用が発生する機能を使用する理由
  • 必要以上に端末情報、個人情報を取得していない、不正アクセをしていないことを表明

また、使用者の不安を取り除くことも大切だが、まずは、設計段階でアプリで使用するパーミッションを必要最低限にすることが大前提だろう。

にほんブログ村 IT技術ブログ Androidアプリ開発へ

2012年1月14日土曜日

android:androidで使用できる暗号方式

androidアプリでは様々な暗号方式を使用することができる。

暗号方式の取得

  • java.security.Securityクラスにより取得できる
  • 聞いたことのない暗号方式も取得できる

package net.kuttya.cryptalgorithmprinter;

import java.security.Security;
import java.util.Set;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;


public class CryptAlgorithmPrinterActivity extends Activity {
    private TextView textAlgorithm;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // 表示領域
        textAlgorithm = (TextView)findViewById(R.id.text_algorithm);
    }

    public void clickEventPrint(View v) {
        // 使用できる暗号方式を取得

        Set<String> algorithms = Security.getAlgorithms("Cipher");

        textAlgorithm.setText("");
        for(String algorithm:algorithms) {
            textAlgorithm.append(algorithm + "\n");
        }
    }
}

  • 直接関係しないがレイアウトは次の通り

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/print"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
            android:onClick="clickEventPrint"
        android:text="暗号方式表示" />

    <ScrollView
        android:id="@+id/scroll_algorithm"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/text_algorithm"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="" />
    </ScrollView>

</LinearLayout>

こんな感じで表示される。
AES、DES、RSAくらいしか聞いたことがない。
まあ、実際に使うのはAESかRSAだと思う。


にほんブログ村 IT技術ブログ Androidアプリ開発へ