【问题标题】:AES128 Decryption :javax.crypto.badpaddingexception pad block corruptedAES128 解密:javax.crypto.badpaddingexception 垫块损坏
【发布时间】:2014-05-06 09:43:31
【问题描述】:

我尝试解密从网络服务收到的加密数据。

使用AES 128完成加密。

我使用以下代码解密数据:

public static String decrypt(String strToDecrypt)
{       
    try
    {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); //AES/CBC/PKCS7Padding
        SecretKeySpec secretKey = new SecretKeySpec(AppConstants.AESEncryptionKey.getBytes("UTF8"), "AES");
        int blockSize = cipher.getBlockSize();
        cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(new byte[blockSize])); //new IvParameterSpec(new byte[16])
        byte decBytes[] = cipher.doFinal(Base64.decode(strToDecrypt, 0));
        // byte decBytes[] = cipher.doFinal(Base64.decodeBase64(strToDecrypt));
        String decStr = new String(decBytes);
        System.out.println("After decryption :" + decStr);
        return decStr;
    }
    catch (Exception e)
    {
        System.out.println("Exception in decryption : " + e.getMessage());
    }
    return null;
}

cipher.doFinal()

我得到以下异常:

javax.crypto.badpaddingexception 垫块损坏

我浏览了我的帖子,但最终没有解决方案。我被困在这里了。

【问题讨论】:

  • 要么加密方使用其他填充(或模式,或密码),要么 strToDecrypt 包含截断或损坏的数据(字符串本身可以是正确的 Base64,但它表示的数据已损坏)。
  • strToDecrypt 拥有完美的 Base64 编码加密数据,甚至填充、模式和算法都相同
  • 在这种情况下,最后一个选项是用于编码和解码的密钥不同:使用错误的密钥解密将导致最后一个块不包含正确填充的数据,并且可以检测到这种情况并导致 BadPaddingException。
  • 不应该是.getBytes("UTF-8")吗?

标签: java android exception encryption aes


【解决方案1】:
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG","Crypto");

完美运行

注意:此代码仅适用于 Android 6 以上的设备。从 Android 7.0 开始,"Crypto"provider has been removed,因此此代码将失败。

【讨论】:

  • 感谢您的回复!!反正我已经解决了这个问题
  • 当我阅读此答案时,我正在重新阅读我的答案。你能指出这个答案如何解决这个问题吗?你在哪里使用生成的随机数?为什么需要指定提供者?为什么选择 SHA1PRNG?
  • 这正好解决了问题。我更喜欢它应该是公认的答案:)
  • 感谢@KingofMasses :)
【解决方案2】:

AES 密钥应由随机数据组成。如果将它们存储为字符串,则可能会丢失信息,尤其是在使用 UTF-8 等编码时。您的线路:

AppConstants.AESEncryptionKey.getBytes("UTF8")

在转换成字符串/从字符串转换过程中,您很可能丢失了数据。如果需要字符串,请改用十六进制,或者将键存储为字节数组。


请注意,此答案并不表示任何与安全相关的提示。通常,您只想派生密钥或将它们存储在容器中。您也不想在不安全的渠道上使用 CBC。

【讨论】:

  • 那我应该如何防止这种损失
  • 改用.getBytes("UTF-8")
  • @petey 不,这个想法是使用十六进制而不是字符编码,例如 UTF-8。显然如何做到这一点已经回答long ago
【解决方案3】:

在我的情况下出现问题是因为加密密钥和解密密钥都不同,当我检查两个具有相同值的密钥时,问题就没有出现

【讨论】:

    猜你喜欢
    • 2017-03-17
    • 2015-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    相关资源
    最近更新 更多