首先,我已经看到 Android 4.2 在 Android 4.2 上破坏了我的 AES 加密/解密代码 和 加密错误 以及提供的解决方案:
SecureRandom sr = null;
if (android.os.Build.VERSION.SDK_INT >= JELLY_BEAN_4_2) {
sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
} else {
sr = SecureRandom.getInstance("SHA1PRNG");
}
对我不起作用,因为在 Android 4.2 中解码 Android<4.2 中加密的数据时,我得到:
javax.crypto.BadPaddingException: pad block corrupted
at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(BaseBlockCipher.java:709)
我的代码非常简单,并且一直工作到 Android 4.2:
public static byte[] encrypt(byte[] data, String seed) throws Exception {
KeyGenerator keygen = KeyGenerator.getInstance("AES");
SecureRandom secrand = SecureRandom.getInstance("SHA1PRNG");
secrand.setSeed(seed.getBytes());
keygen.init(128, secrand);
SecretKey seckey = keygen.generateKey();
byte[] rawKey = seckey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
return cipher.doFinal(data);
}
public static byte[] decrypt(byte[] data, String seed) throws Exception {
KeyGenerator keygen = KeyGenerator.getInstance("AES");
SecureRandom secrand = SecureRandom.getInstance("SHA1PRNG");
secrand.setSeed(seed.getBytes());
keygen.init(128, secrand);
SecretKey seckey = keygen.generateKey();
byte[] rawKey = seckey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
return cipher.doFinal(data);
}
我的猜测是默认提供程序并不是 Android 4.2 中唯一改变的东西,否则我的代码将适用于建议的解决方案。
我的代码基于很久以前在 StackOverflow 上找到的一些帖子;我看到它与提到的帖子不同,因为它只是加密和解密字节数组,而其他解决方案加密和解密字符串(我认为是 HEX 字符串)。
跟种子有关系吗?它是否有最小/最大长度、字符限制等?
任何想法/解决方案?
编辑:经过大量测试,我发现有两个问题:
在 Android 4.2 (API 17) 中更改了提供程序-> 这个很容易修复,只需应用我在帖子顶部提到的解决方案
BouncyCastle 在 Android 2.2 (API 8)->Android2.3 (API 9) 中从 1.34 更改为 1.45,所以我之前讲的解密问题和这里描述的一样:BouncyCastle AES error when upgrade to 1.45
所以现在的问题是:有没有办法在 BouncyCastle 1.45+ 中恢复在 BouncyCastle 1.34 中加密的数据?