这个怎么样:
- 在 .SO 中存储一个字节 [16]。如果您不使用 .SO,那么就为此目的制作一个。
- 使用该字节数组加密一个新字节[16],然后 Base64 编码结果。在你的类文件中硬编码。
现在您已经设置了密钥,让我解释一下:
是的,可能有人可以窥视 .SO 并找到字节数组,从而找到您的密钥。但是由于加密的 key2 是 base64 编码的,他需要对其进行解码并使用所述密钥反转加密以提取 key2 字节。到目前为止,这只涉及拆卸应用程序。
- 当您要存储加密数据时,首先使用 key1 进行 AES 传递,然后使用 Key2 和 IV* 进行 AES/CBC/Padding5 传递
- 如果您想在每次存储新密码时更改 IV,您可以安全地对 IV 进行 Base64 编码并将其保存在 /data/data 文件夹中。
通过这两个步骤,不再需要拆卸应用程序,因为现在还需要控制运行时以获取加密数据。您不得不说对于存储的密码来说已经足够了。
然后你可以简单地将它存储到 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 但我为您提供了一个解决存储敏感数据问题的可行解决方案:)