您好我在Android上根据用户提供的密码解密文件时遇到以下异常:
Caused by: java.lang.ArrayIndexOutOfBoundsException: src.length=1024 srcPos=1008 dst.length=16 dstPos=16 length=16
at java.lang.System.arraycopy(Native Method)
at com.android.org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher.processBytes(PaddedBufferedBlockCipher.java:221)
at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$BufferedGenericBlockCipher.processBytes(BaseBlockCipher.java:882)
at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineUpdate(BaseBlockCipher.java:674)
at javax.crypto.Cipher.update(Cipher.java:893)
at javax.crypto.CipherOutputStream.write(CipherOutputStream.java:95)
它只是在Android 4+上随机发生在Google Play商店的崩溃报告中。它曾经用于旧版本。
我的加密包装器:
private static final String KEY_FACTORY_ALGORITHM = "PBEWITHSHAAND128BITAES-CBC-BC";
private static final String KEY_ALGORITHM = "AES";
private static final String CIPHER_PROVIDER = "AES";
public Crypto(String password, byte[] salt) {
if (TextUtils.isEmpty(password)) {
throw new IllegalArgumentException(
"password cannot be null or empty.");
}
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 20,
128);
SecretKeyFactory factory;
try {
factory = SecretKeyFactory.getInstance(KEY_FACTORY_ALGORITHM);
PBEKey key = (PBEKey) factory.generateSecret(keySpec);
this.createKeyAndCipher(key.getEncoded());
} catch (Exception e) {
Log.e(this.getClass().getName(), Log.getStackTraceString(e));
throw new RuntimeException(e);
}
}
private void createKeyAndCipher(byte[] keyData)
throws NoSuchAlgorithmException, NoSuchPaddingException {
_secretKey = new SecretKeySpec(keyData, KEY_ALGORITHM);
_cipher = Cipher.getInstance(CIPHER_PROVIDER);
}
执行解密的功能:
public void decrypt(InputStream input, OutputStream output)
throws Throwable {
_cipher.init(Cipher.DECRYPT_MODE, _secretKey);
this.encryptDecrypt(input, output);
}
public void encryptDecrypt(InputStream input, OutputStream output) throws Throwable {
final int BUFFER_SIZE = 1024;
CipherOutputStream cipherStream = new CipherOutputStream(output,
_cipher);
byte[] buffer = new byte[BUFFER_SIZE];
int count = -1;
while ((count = input.read(buffer)) != -1) {
cipherStream.write(buffer, 0, count);
}
input.close();
cipherStream.close();
}
在Boucycastle的Android 4版本中有什么变化吗?
任何提示都非常赞赏。
谢谢。
将代码更改为:
public void encryptDecrypt(InputStream input, OutputStream output) {
final int BUFFER_SIZE = 1024;
try {
byte[] buffer = new byte[BUFFER_SIZE];
int count = -1;
while ((count = input.read(buffer)) != -1) {
byte[] result = null;
if (count == BUFFER_SIZE) {
result = _cipher.update(buffer, 0, count);
} else {
result = _cipher.doFinal(buffer, 0, count);
}
if (result != null) {
output.write(result);
}
}
input.close();
output.close();
} catch (Exception e) {
Log.e(this.getClass().getName(), Log.getStackTraceString(e));
throw new RuntimeException(e);
}
}
现在我要
了javax.crypto.BadPaddingException: pad block corrupted
有一点需要注意:只有当我尝试解密文件时才会发生这种情况。来自_cipher.doFinal(arra)解密的sqlite的短字节[]可以使用相同的密钥正常工作。
此外,在帖子开头的原始错误中,
dst.length=16 dstPos=16 length=16
我已经读过一些关于AES和数据的信息比16更短。