解密文件时出现ArrayIndexOutOfBoundsException

时间:2014-06-04 18:33:21

标签: android bouncycastle

您好我在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版本中有什么变化吗?

任何提示都非常赞赏。

谢谢。

UPDATE:

将代码更改为:

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更短。

0 个答案:

没有答案