Cipher在一个大块中返回整个文件

时间:2018-04-22 19:49:55

标签: android encryption aes aes-gcm

我们在Android应用中使用CipherCipherInputStream来解密从服务器下载的文件。

由于某种原因,对Cipher.update的所有调用都返回一个空块,对Cipher.doFinal的调用将在一个块中返回整个文件。

这会导致大文件上的OOM。

这是我们用来初始化密码的代码:

final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec key = new SecretKeySpec(keyData, "AES");
GCMParameterSpec nonce = new GCMParameterSpec(128, nonceData);
cipher.init(Cipher.DECRYPT_MODE, key, nonce);
  1. 为什么会这样?
  2. 这是否可以在客户端修复?
  3. 注意:我目前无法访问服务器的代码。我有的时候也会发布。 注意2:这在Android API 25.0.1上发生

1 个答案:

答案 0 :(得分:1)

好问题!这是因为您正在使用GCM模式。无法检查身份验证标记,直到从服务器收到所有数据,因此Java会自动缓冲此数据,检查数据,然后在检查标记后为您提供最终数据。

GCM模式非常适合相对较小的邮件大小或文件,但大文件不应使用GCM模式加密。

您可能更喜欢将CBC模式与HMAC一起使用,将文件流式传输到磁盘,验证HMAC并然后解密。它更加迂回,但避免了您目前所遇到的问题。