Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/233.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android密码抛出BadPaddingException,但不是在Java中_Android_Encryption - Fatal编程技术网

Android密码抛出BadPaddingException,但不是在Java中

Android密码抛出BadPaddingException,但不是在Java中,android,encryption,Android,Encryption,我在运行Android v20(4.4.4)的应用程序中使用了一些基本的加密 这过去是可行的,但我认为在我运行的较新版本Android中,现在出现了一个引发以下异常的错误: 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﹕ a

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

这过去是可行的,但我认为在我运行的较新版本Android中,现在出现了一个引发以下异常的错误:

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)
方法如下:

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)

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

我正在使用的getRawKey方法:

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();
}

感谢您的帮助。

使用
SecureRandom
派生密钥的问题在于:

  • SecureRandom
    使用未定义的算法,该算法可能在不同实现之间发生变化(即使来自同一供应商)
  • 事实上,
    SecureRandom
    只使用给定的种子作为熵是有缺陷的,这可能(并且确实)会因不同的实现而改变
如果您指定了
“SHA1PRNG”
,这不是一个定义良好或标准化的算法,则上述情况也是正确的

在安卓系统中,Oracle提供程序中的
SecureRandom
的专有功能——以及试图保持兼容的提供程序——被改为支持OpenSSL相关的提供程序。这是从4.2开始发生的。在OpenSSL中,
SecureRandom
仅将给定种子混合到熵池中。换句话说,即使使用与seed相同的“密码”,也会得到一个完全随机的密钥


因此,如果您看到上面定义的
getRawKey
,请尝试将其取下。对于您自己的实现,只需使用
SecretKeySpec
作为密钥,或使用PBKDF2作为密码

您是否使用了臭名昭著的
getRawKey
函数,该函数试图使用种子和随机数生成器重新生成AES密钥?嗯。。。对我从一篇博客文章中复制了这个方法,这是你搜索如何做的第一个结果。实际上我正要更新这个答案,我让它工作了,但是当这个问题出现时,我不得不重新加密我试图解密的加密密钥。我使用的方法会使这个问题继续发生吗?我将把getRawKey方法添加到问题中以供参考。请注意,
Cipher.getInstance(“AES”)
使用提供程序的默认操作模式和填充模式。这主要意味着ECB操作模式和PKCS#7兼容填充。PKCS#7填充是可以的(除非使用填充oracle攻击)。ECB不是,请使用CBC或-如果可用-GCM模式加密。