在 Android 中使用分块解密时最后丢失字节
Losing bytes at the end when using chunked decryption in Android
首先,我在 Java/Android 中创建了一个 encryption/decryption 小程序。这没什么特别的,只是非常基本,所以没有缓冲区或任何东西。使用了 Iv 和 Salt,我在文件的开头写了 salt 和 iv(24 字节)。第一个版本能够 en/decrypt 一个文件和两个文件,最终二进制文件相同。
现在我尝试不一次读取和处理整个文件,而是使用缓冲区(大小 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。
and
2.加密解密的文件末尾少了29字节。
不用担心,Iv 和盐通常是随机的,只是用于测试的静态。
此外,丢失的字节数取决于文件大小。刚刚尝试了另一个文件,它缺少 21 个字节。
您正在丢弃加密和解密例程中 doFinal()
的输出。这些 return 和 byte[]
也必须写入您的输出,以便加密的密文或解密的明文完整有效。
首先,我在 Java/Android 中创建了一个 encryption/decryption 小程序。这没什么特别的,只是非常基本,所以没有缓冲区或任何东西。使用了 Iv 和 Salt,我在文件的开头写了 salt 和 iv(24 字节)。第一个版本能够 en/decrypt 一个文件和两个文件,最终二进制文件相同。
现在我尝试不一次读取和处理整个文件,而是使用缓冲区(大小 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。
and
2.加密解密的文件末尾少了29字节。
不用担心,Iv 和盐通常是随机的,只是用于测试的静态。
此外,丢失的字节数取决于文件大小。刚刚尝试了另一个文件,它缺少 21 个字节。
您正在丢弃加密和解密例程中 doFinal()
的输出。这些 return 和 byte[]
也必须写入您的输出,以便加密的密文或解密的明文完整有效。