ナツ 「やっぱアキは、マニアックなとこまで調べてるね〜」
アキ 「まあ、AndroidはOSのソースコードとかも公開されてるから調べやすいよね」
ジュン 「いや、調べやすいよねっていわれても、ソースコード読むの大変だし」
アキ 「そうかなー。結構楽しいけど」
クウ 「ログ以外でも、やっぱりマルウェアとかに情報取られちゃうものとかってあるんですか?」
アキ 「あとは、SDカードへの書き出しも地味に危ないよね。実は、インストールのときに何も聞かれないのに、SDカード読めるし」
クウ 「え? SDカードって、パーミッションとかなしで読めるんですか??」
アキ 「パーミッションは存在するけど、なくてもいいんだよね〜、これが」
Androidのシステムでは、SDカードへの書き込みにはandroid.permission.WRITE_EXSTERNAL_STORAGEというパーミッションが用意されている。だがSDカードの読み込みは、パーミッションの指定がなくても可能だ。
この点には十分な注意が必要だ。アプリケーションを開発する開発者はもちろん、利用するユーザーも、SDカードに重要な情報を残さないようにすべきだろう。例えば、電話帳移行などの際に電話帳データをそのままにしていたり、ダウンロードしたファイルがそのままだったり、写真データがそのままだったりすると、非常に危険である。
クウ 「いろいろできるから、ある程度危ないこともあり得るかな〜くらいしか認識してなかったですけど、結構ちゃんと考えないといけないんですね……」
ジュン 「私もあんまり考えないで使ってた〜。SDカードの中に電話帳のエクスポートデータ入ったままだ……」
もし、バックアップを行ってそのデータをPCにコピーしたり、外部のシステムなどと連携するために、SDカードに重要な情報を出力する必要がある場合は、ファイルを奪取される可能性を考慮する必要がある。
通常のデータ領域であれば、Linuxコマンドのchmodなどでファイルの読み込み権限のパーミッションを変更することが可能だ。だがSDカード領域では、パーミッションの変更ができない。
従って、暗号化を行ったり、パスワード付きZIP(Android標準のAPIは、パスワード付きZIPの機能は有していないので注意が必要)にしたりするなど、漏えいした場合にも影響を最小限に抑えるための対策が必要となる。暗号化、パスワード付きZIPいずれの場合においても、その鍵となるパスワードはSDカードなどで受け渡しができない。このため、ユーザーが指定できるようにするなどの工夫が必要となる。
//ランダムなパスワードまたはユーザー指定のパスワードの取得 byte[] secretKey = getSecretKey(); String data = "重要データ"; //暗号化の実行 SecretKeySpec sKey = new SecretKeySpec(secretKey, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, sKey); byte[] iv = cipher.getIV(); byte[] encData = cipher.doFinal(data.getBytes()); //ファイルへの書き込み String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/encrypted.dat"; FileOutputStream out = new FileOutputStream(filePath); out.write(iv); out.write(encData); out.close();
//暗号化時に指定したパスワードの取得 byte[] secretKey = getSecretKey(); //暗号化データの取得 String data = readFile(); //暗号化データの復号 SecretKeySpec sKey = new SecretKeySpec(secret_key, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); ByteArrayOutputStream iv = new ByteArrayOutputStream(); iv.write(encData, 0, 16); ByteArrayOutputStream data = new ByteArrayOutputStream(); data.write(encData, 16, encData.length-16); IvParameterSpec ivparameterspec = new IvParameterSpec(iv.toByteArray()); cipher.init(Cipher.DECRYPT_MODE, sKey, ivparameterspec); //復号後の文字列の取得 byte[] decryptedData = cipher.doFinal(data.toByteArray());
クウ 「むむむ……。ここでも暗号化ですか〜」
ナツ 「そうだねぇ。何をするにも『情報を守る』っていう意識を持っておかないとダメだねー」
アキ 「基本全部暗号化する! 余計な情報は一切出さない! って考えればシンプルじゃない?」
ナツ 「確かに、シンプルだけど……。大変だね」
ジュン 「まあ、安全にするならこれくらいしないと!ってことだね」
【クウたちの壁紙カレンダー、配布中!】
本連載のイラストを担当しているはるぷさんによる、毎月更新のカレンダーが配布されています。ぜひご利用ください!
特製ウォールペーパー
http://www.ubsecure.jp/wallpaper.php
杉山 俊春(すぎやま としはる)
株式会社ユービーセキュア
技術本部 VEXグループ リーダー 兼 セキュリティオーディットコンサルタント
セキュリティコンサルタントとして、主にWebアプリケーションのセキュリティ検査やWebアプリケーション検査ツールの開発などに従事している。大手ショッピングサイトなどの検査実績を持つ。
Copyright © ITmedia, Inc. All Rights Reserved.