Android向け非同期HTTPクライアントで生体信号を安全に送信する方法

Androidアプリ開発において、生体データ(心拍、指紋、脳波など)の送信にはセキュリティと非同期処理が不可欠です。ここでは、軽量かつ拡張性に優れたandroid-async-httpライブラリを活用し、暗号化された生体情報をサーバーへ安全に送信する実装手順を解説します。

なぜこのライブラリが生体データ送信に適しているのか

  • メインスレッドをブロックしない:コールバックベースの非同期設計により、UIのフリーズを回避
  • SSL/TLSカスタマイズ対応:独自の証明書検証やピンニング設定が可能
  • リクエスト前処理機構:送信前にデータを暗号化するインターセプターを簡単に実装
  • 低メモリフットプリント:古い端末でも動作しやすい軽量設計

実装ステップ概要

  1. プロジェクトにライブラリを追加
  2. 生体データをAES-256で暗号化
  3. HTTPS接続にカスタムSSLファクトリを設定
  4. 非同期POSTでデータ送信

1. ライブラリのセットアップ

Gradle依存関係に以下を追加:

implementation 'com.loopj.android:android-async-http:1.4.11'

2. 暗号化ヘルパーの作成

public class BioEncryptor {
    private static final String ALGORITHM = "AES/GCM/NoPadding";
    private final SecretKey key;

    public BioEncryptor(byte[] rawKey) {
        this.key = new SecretKeySpec(rawKey, "AES");
    }

    public byte[] encrypt(byte[] rawData) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        byte[] iv = new byte[12];
        new SecureRandom().nextBytes(iv);
        GCMParameterSpec spec = new GCMParameterSpec(128, iv);
        cipher.init(Cipher.ENCRYPT_MODE, key, spec);
        
        byte[] encrypted = cipher.doFinal(rawData);
        return ByteBuffer.allocate(iv.length + encrypted.length)
                        .put(iv).put(encrypted).array();
    }
}

3. セキュアなHTTPクライアントの構築

public class SecureBioClient {
    private final AsyncHttpClient client;
    
    public SecureBioClient(Context context) {
        this.client = new AsyncHttpClient();
        this.client.setSSLSocketFactory(
            new MyPinningSocketFactory(context.getAssets().open("server_cert.cer"))
        );
        this.client.setTimeout(15000); // 15秒タイムアウト
    }

    public void sendEncryptedBioData(String endpoint, byte[] bioData, 
                                   ResponseHandlerInterface handler) {
        RequestParams params = new RequestParams();
        try {
            BioEncryptor encryptor = new BioEncryptor(getSecureKey());
            byte[] encrypted = encryptor.encrypt(bioData);
            params.put("payload", Base64.encodeToString(encrypted, Base64.NO_WRAP));
            client.post(endpoint, params, handler);
        } catch (Exception e) {
            handler.sendFailureMessage(0, null, null, e);
        }
    }
    
    private byte[] getSecureKey() {
        // 実際はAndroid Keystoreから取得すべき
        return "your-32-byte-secret-key-here-123".getBytes();
    }
}

4. 非同期送信の呼び出し

SecureBioClient bioClient = new SecureBioClient(this);
bioClient.sendEncryptedBioData(
    "https://api.biometric.example/upload",
    heartRateData.getBytes(),
    new AsyncHttpResponseHandler() {
        @Override
        public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
            Log.d("BioUpload", "データ送信成功: " + new String(responseBody));
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, 
                            byte[] responseBody, Throwable error) {
            Log.e("BioUpload", "送信失敗: " + error.getMessage());
        }
    }
);

セキュリティ強化のベストプラクティス

  • 鍵管理:ハードコードせず、Android Keystore Systemを使用
  • 証明書固定:中間者攻撃対策としてサーバー証明書のハッシュをアプリ内に保持
  • 通信監査:送信ログをローカルに記録し、異常アクセスを検知
  • 再送制御:失敗時は指数バックオフ方式でリトライ

パフォーマンス最適化のヒント

  • 生体データは送信前に差分圧縮(例:Delta encoding)を適用
  • 同時接続数を3〜5に制限し、帯域を過剰に消費しないようにする
  • 低電力モード時は送信頻度を自動調整する仕組みを導入

タグ: android-async-http AES-GCM SSL-Pinning Biometric-Data AsyncHttpClient

6月25日 20:28 投稿