これはどう:
- byte[16] を .SO に格納します。.SO を使用しない場合は、その目的のためだけに作成してください。
- そのバイト配列を使用して新しいバイト [16] を暗号化し、結果を Base64 エンコードします。クラスファイルにハードコードします。
キーのセットアップが完了したので、説明させてください。
はい、潜在的に.SOをのぞき見して、キーの代わりにバイト配列を見つけることができます。しかし、暗号化された key2 が base64 でエンコードされている場合、key2 バイトを抽出するには、それをデコードし、前述のキーで暗号化を逆にする必要があります。これまでのところ、これにはアプリの逆アセンブルのみが含まれます。
- 暗号化されたデータを保存する場合は、最初に key1 で AES パスを実行し、次に Key2 と IV* で AES/CBC/Padding5 パスを実行します。
- 新しいパスワードが保存されるたびに IV を変更したい場合は、IV を安全に Base64 エンコードして /data/data フォルダーに保存することができます。
この 2 つの手順により、アプリを逆アセンブルするだけでなく、暗号化されたデータにアクセスするためにランタイムを制御する必要が生じます。あなたが言わなければならないことは、保存されたパスワードにはかなり十分です.
次に、それを単純に SharedPreferences に保存できます :) そうすれば、SharedPreferences が危険にさらされても、データは引き続きロックされます。サブクラス化が本当に正しいアプローチだとは思いませんが、すでにクラスを作成しているので、まあまあです。
ここに、私が何を意味するかをさらに説明するためのコードがあります
//use to encrypt key
public static byte[] encryptA(byte[] value) throws GeneralSecurityException, IOException
{
SecretKeySpec sks = getSecretKeySpec(true);
System.err.println("encrypt():\t" + sks.toString());
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sks, cipher.getParameters());
byte[] encrypted = cipher.doFinal(value);
return encrypted;
}
//use to encrypt data
public static byte[] encrypt2(byte[] value) throws GeneralSecurityException, IOException
{
SecretKeySpec key1 = getSecretKeySpec(true);
System.err.println("encrypt():\t" + key1.toString());
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key1, cipher.getParameters());
byte[] encrypted = cipher.doFinal(value);
SecretKeySpec key2 = getSecretKeySpec(false);
System.err.println("encrypt():\t" + key2.toString());
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key2, new IvParameterSpec(getIV()));
byte[] encrypted2 = cipher.doFinal(encrypted);
return encrypted2;//Base64Coder.encode(encrypted2);
}
//use to decrypt data
public static byte[] decrypt2(byte[] message, boolean A) throws GeneralSecurityException, IOException
{
SecretKeySpec key1 = getSecretKeySpec(false);
System.err.println("decrypt():\t" + key1.toString());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key1, new IvParameterSpec(getIV()));
byte[] decrypted = cipher.doFinal(message);
SecretKeySpec key2 = getSecretKeySpec(true);
System.err.println("decrypt():\t" + key2.toString());
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key2);
byte[] decrypted2 = cipher.doFinal(decrypted);
return decrypted2;
}
//use to decrypt key
public static byte[] decryptKey(String message, byte[] key) throws GeneralSecurityException
{
SecretKeySpec sks = new SecretKeySpec(key, ALGORITHM);
System.err.println("decryptKey()");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
byte[] decrypted = cipher.doFinal(Base64Coder.decode(message));
return decrypted;
}
//method for fetching keys
private static SecretKeySpec getSecretKeySpec(boolean fromSO) throws NoSuchAlgorithmException, IOException, GeneralSecurityException
{
return new SecretKeySpec(fromSO ? getKeyBytesFromSO() : getKeyBytesFromAssets(), "AES");
}
どう思いますか?
独自の SharedPreferences の使用について尋ねているため、トピックから外れている可能性があることは認識していますが、機密データの保存の問題に対する実用的な解決策を提供しています:)