Android Cipher抛出BadPaddingException,但不是在Java中 [英] Android Cipher throwing BadPaddingException, but not in Java

查看:82
本文介绍了Android Cipher抛出BadPaddingException,但不是在Java中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在运行Android v20(4.4.4)的应用程序中使用了一些基本加密

I'm using some basic encryption in my app, which is running Android v20 (4.4.4)

这曾经可以工作,但是我认为我正在运行的较新版本的Android出现错误,引发以下异常:

This used to work, but I think with the newer version of Android I'm running, there is now an error throwing the following exception:

10-28 12:42:02.312    5173-5332/com.app W/System.err﹕ javax.crypto.BadPaddingException: pad block corrupted
10-28 12:42:02.312    5173-5332/com.app W/System.err﹕ at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(BaseBlockCipher.java:739)
10-28 12:42:02.322    5173-5332/com.app W/System.err﹕ at javax.crypto.Cipher.doFinal(Cipher.java:1204)
10-28 12:42:02.322    5173-5332/com.app W/System.err﹕ at com.app.utils.CryptoClass.decrypt(CryptoClass.java:47)
10-28 12:42:02.322    5173-5332/com.app W/System.err﹕ at com.app.utils.CryptoClass.decrypt(CryptoClass.java:30)

抛出该错误的方法在这里:

The method throwing this is here:

private static byte[] decrypt(byte[] rawKey, byte[] encrypted) throws Exception {
    SecretKeySpec spec = new SecretKeySpec(rawKey, "AES");
    Cipher cipher = Cipher.getInstance("AES");

    cipher.init(Cipher.DECRYPT_MODE, spec);

    return cipher.doFinal(encrypted); //THIS LINE THROWS EXCEPTION
}

当我运行与Java项目相同的代码时,它可以正常工作(使用与Android使用的Java版本1.7相同的版本).

When I run this same code as a Java project, it works correctly (using the same version of Java, 1.7 as Android is using).

我已经根据我在网上找到的内容尝试了getInstance参数的各种组合,例如 AES/CBC/PKCS5PADDING ,但这不能解决问题.

I've tried various combinations for the getInstance parameter based on what I've found online, like AES/CBC/PKCS5PADDING but that doesn't solve the problem.

我正在使用的getRawKey方法:

The getRawKey method I'm using:

private static byte[] getRawKey(byte[] bytes) throws Exception {
    KeyGenerator keygen = KeyGenerator.getInstance("AES");
    SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "SECRET");

    secureRandom.setSeed(bytes);
    keygen.init(128, secureRandom);

    SecretKey secretKey = keygen.generateKey();
    return secretKey.getEncoded();
}

任何帮助表示感谢,谢谢.

Any help appreciated, thanks.

推荐答案

使用 SecureRandom 导出密钥的问题是:

The problem of using SecureRandom to derive keys is that:

  • SecureRandom 使用一种未定义的算法,该算法可能会在不同的实现之间更改(即使来自同一供应商).
  • SecureRandom 仅使用给定种子作为熵的事实是有缺陷的,对于不同的实现,这可能(并且确实)会发生变化.
  • SecureRandom uses an undefined algorithm, which may change between implementations (even from the same vendor).
  • the fact that SecureRandom only uses the given seed as entropy is flawed, this may (and does) change for different implementations.

如果您指定的"SHA1PRNG" (定义不明确或标准化的算法),以上甚至是正确的.

Above is even true if you specify "SHA1PRNG", which is not a well defined or standardized algorithm.

在Android中,Oracle提供程序中的 SecureRandom 的专有功能-以及试图保持兼容的提供程序-已更改为支持与OpenSSL相关的提供程序.这是从4.2开始发生的.在OpenSSL中, SecureRandom 仅将给定的种子混合到熵池中.换句话说,即使您使用与种子相同的密码",也可以获得完全随机的密钥.

In Android, the proprietary functionality of SecureRandom in the Oracle provider - and the providers that tried to stay compatible - was changed in favor of the OpenSSL related provider. This happened from 4.2 onwards. In OpenSSL, SecureRandom only mixes the given seed into the entropy pool. In other words, you get a fully random key even if you use the same "password" as seed.

因此,如果您看到如上定义的 getRawKey ,请尝试将其删除.对于您自己的实现,只需对密钥使用 SecretKeySpec 或对密码使用PBKDF2.

So if you ever see getRawKey as defined as above, please try and take it down. And for your own implementations just use SecretKeySpec for keys or PBKDF2 for passwords.

这篇关于Android Cipher抛出BadPaddingException,但不是在Java中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆