这个怎么样:
- 在 .SO 中存储一个字节 [16]。如果您不使用 .SO,请为此目的制作一个。
- 使用该字节数组加密一个新字节[16],然后对结果进行 Base64 编码。在你的类文件中硬编码。
现在你已经设置了密钥,让我解释一下:
是的,可能有人可以窥视 .SO 并找到字节数组,从而成为您的密钥。但是由于加密的 key2 是 base64 编码的,他需要对其进行解码并使用所述密钥反转加密以提取 key2 字节。到目前为止,这只涉及拆解应用程序。
- 当您要存储加密数据时,首先使用密钥 1 进行 AES 传递,然后使用密钥 2 和 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,但我正在为您提供存储敏感数据问题的有效解决方案 :)