加密大字节数组

问题描述 投票:3回答:1

我正在使用Cipher进行加密/解密。一直很好,但是现在在处理大数组字节时遇到问题。

这是我的实现:

val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey())
val encryptedData = cipher.doFinal(textToEncrypt.toByteArray(StandardCharsets.UTF_8))

如上所述,仅当输入文本太大时,问题才会发生。例如,如果我将长度为168036的字节数组作为doFinal的输入传递,它将给我返回长度为65652的字节数组。

这与密码的限制有关吗?如果可以,是否有增加输入缓冲区的方法?

enter image description here

java android kotlin encryption aes-gcm
1个回答
3
投票

[GVillani82显示,他沉迷于一些严肃的Google-Fu;从评论中:

“可能与此https://issuetracker.google.com/issues/123307358相关?”

[表明这很可能是运行时27及更低版本中的错误。大概在更高版本中已修复,尽管错误报告没有说哪个版本。


但是,最好使用增量更新来解决此问题。在这种情况下,请确保您的缓冲区严格低于64KiB,例如32KiB。

基本上,在Java中,有两种方法可以执行增量加密。一种是简单地使用许多Cipher.update方法之一,并从缓冲区中为其提供文本(请注意,Cipher.update在可用时会返回部分密文)。然后,您需要使用doFinal()方法来完成加密。

另一个是使用流式传输。对于加密,通常使用CipherOutputStream,然后手动将明文复制到该明文中(或者再次使用缓冲区),或者如果要写入整个流,则只需执行InputStream.transferTo方法即可。在这种情况下,您可能希望直接从资源中读取字节(保持原始编码)。但是,在这种情况下,您不知道它将使用什么缓冲区大小。如果您需要流,那么使用update / doFinal调用创建自己的流类相对容易。

[使用输入和输出缓冲区(doFinal)的ByteBuffer似乎仍然会触发错误,因此将无法使用。

© www.soinside.com 2019 - 2024. All rights reserved.