私は現在、クライアントサーバーアーキテクチャに基づくAndroidアプリケーションに取り組んでいます。データのセキュリティのために、データの暗号化と署名に公開鍵と秘密鍵のペアを使用しています。キーペアの保存に AndroidKeyStore を使用しています。以下は、鍵ペアを生成するコードです。
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(
mContext)
.setAlias(mPrivateKeyAlias)
.setSubject(new X500Principal("CN=" + mPrivateKeyAlias))
.setSerialNumber(
BigInteger.valueOf(System.currentTimeMillis()))
.setStartDate(start.getTime())
.setEndDate(end.getTime()).setKeySize(2048).build();
KeyPairGenerator kpGenerator = KeyPairGenerator.getInstance(
"RSA",
"AndroidKeyStore");
kpGenerator.initialize(spec);
// Key Pair will be saved in AndroidKeyStore
KeyPair pair = kpGenerator.generateKeyPair();
このコードを実行すると、キーストア関連ファイル (CERT および PKEY ファイル) が「/data/misc/keystore/user_0/」ディレクトリに生成されます。セキュリティ上の理由から、auth-token などのアプリケーションの機密データを暗号化し、Shared Pref に保存しています。
ただし、ユーザーがデバイスのパスワードまたは PIN を変更すると、キーストアの暗号化に使用されるマスターキーがデバイスの資格情報を使用して生成されるため、キーストア ファイルが削除されます。
この問題を修正するために、公開鍵と秘密鍵のペアを RAM に保持し、パスワードが変更されたときにしようとしました。DeviceAdminReceiver の onPasswordChanged(Context context, Intent intent) メソッドから、以下のコードを実行しています。
KeyStore keyStore = KeyStore
.getInstance("AndroidKeyStore");
keyStore.load(null);
keyStore.setKeyEntry(mPrivateKeyAlias, mPrivateKey.getPrivateKey(),
null, new Certificate[] { mPrivateKey.getCertificate() });
ただし、このコードの後、'/data/misc/keystore/user_0/'
ディレクトリに CERT ファイルのみが作成され、秘密鍵を使用して復号化すると、無効な署名エラーが発生します。
また、公開鍵をサーバーと共有し、データを秘密鍵で暗号化したため、新しい鍵ペアを作成することはより良い解決策ではありません。
では、デバイスのパスワードを変更した後、公開秘密鍵のペアを保持するにはどうすればよいですか? 回避策がない場合、AndroidKeyStore の正確な用途は何ですか? どこで使用できますか?