【问题标题】:Losing bytes at the end when using chunked decryption in Android在 Android 中使用分块解密时最后丢失字节
【发布时间】:2015-11-04 01:19:48
【问题描述】:

首先,我在 Java/Android 中创建了一个小加密/解密程序。这没什么特别的,只是非常基本,所以没有缓冲区或任何东西。在那里使用了 Iv 和 Salt 我在文件开头写了 salt 和 iv (24 bytes) 。第一个版本能够加密/解密一个文件,并且两个文件最终的二进制文件相同。

现在我尝试不一次读取和处理整个文件,而是使用缓冲区(大小为 1024 字节)分步进行。我将我的cipher.doFinal 更改为多个 cipher.update 和一个空的cipher.doFinal 最后。

加密:

byte[] salt = {1, 2, 3, 4, 5, 6, 7, 8};
byte[] iv = {23, 45, 23, 12 , 39, 111, 90, 1, 2, 3, 4, 5, 6, 7, 8, 9};

FileInputStream fis = new FileInputStream(f);
byte[] buffer = new byte[1024];

byte[] output = new byte[24];
cpyArray(iv, output, 0);
cpyArray(salt, output, 16);

FileOutputStream fos = new FileOutputStream(new File(f.getPath() + ".enc"));
fos.write(output);


Cipher cipher = getcCipher(pass, salt,iv, Cipher.ENCRYPT_MODE);

for(int length; (length = fis.read(buffer)) > 0; ) { 
    byte[] realbuffer = new byte[length];
    if (length != 1024) {
        cpyArrayUntil(buffer, realbuffer, 0, length);
    } else {
        realbuffer = buffer;
    }
    byte[] chipped = cipher.update(realbuffer)
    fos.write(chipped);
    System.out.println("Chipped: " + chipped.length);
}
cipher.doFinal();
fis.close();
fos.close();

解密:

 Cipher cipher = getcCipher(pass, salt, iv, Cipher.DECRYPT_MODE);
byte[] buffer = new byte[1024];
for(int length; (length = fis.read(buffer)) > 0; ) {
    byte[] realbuffer = new byte[length];
    if (length != 1024) {
        cpyArrayUntil(buffer, realbuffer, 0, length);
    } else {
        realbuffer = buffer;
    }
    byte[] chipped = cipher.update(realbuffer)
    fos.write(chipped);
    System.out.println("Chipped: " + chipped.length);
}
cipher.doFinal();

所以,现在的问题是,当我运行它并最后比较文件时,
1. 我在解密时在 doFinal 上得到一个 BadPaddingExeption。 和
2. 被加密和解密的文件在文件末尾缺少 29 个字节。

不用担心,IV 和盐通常是随机的,只是静态测试。

此外,丢失的字节取决于文件大小。刚刚尝试了另一个文件,它缺少 21 个字节。

【问题讨论】:

  • 检查文件格式 UTF-8 ANSI ...它可能是缺少 29 个字节.. 尝试使用相同的文件格式写入/读取文件
  • 尽管缺少 29 个字节,但文件是否与预期文件匹配?之前写入的字节是否正确?
  • 1.所有字节完全相同,解密文件末尾仅缺少 29 个字节。 2. UTF-8 之类的格式无关紧要,我不会将字节转换为字符串或其他东西,而是将它们与十六进制编辑器进行逐字节比较。
  • CipherOutputStreamCipherInputStream 将清理您的代码并消除您疯狂的缓冲区管理中的一些潜在错误。编辑您的问题以反映当前情况。您是否更改了代码以便现在在加密时编写doFinal() 的结果?然后您的帖子应该显示该代码并清楚地描述您当前遇到的错误。评论不如修改清晰。

标签: java android encryption aes badpaddingexception


【解决方案1】:

您在加密和解密例程中都丢弃了doFinal() 的输出。它们都返回一个byte[],它也必须写入您的输出,以使加密的密文或解密的明文完整且有效。

【讨论】:

  • 是的,可能是真的,但我有一个问题:解密时,doFinal 会抛出一个 BadPadding Exeption,即使使用正确的密钥和一切。现在,如果它抛出异常,它不会返回任何东西,它会跳到 catch 块中。
  • 好的,这似乎一次性解决了这两个问题,谢谢。我现在将两个决赛返回的字节也写入文件,它似乎工作正常。遗憾的是,目前没有时间对其进行全面测试。
  • @Julian 你是如何解决 BadPaddingException 的?看来你还没有分享完整的代码。
  • @ArtjomB。似乎很可能由于在加密期间丢弃 doFinal() 的结果而丢失的数据是导致使用 BadPaddingException 解密失败的原因,因此修复加密过程同时解决了解密问题(因此“这似乎一次性解决了这两个问题”)。
猜你喜欢
  • 1970-01-01
  • 2018-09-05
  • 2019-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-12
  • 2011-04-23
  • 2013-01-14
相关资源
最近更新 更多