加密大字节数组

Encrypting large byte array

我正在为 encryption/decryption 使用 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 的字节数组。

这与Cipher的限制有关吗?如果是这样,有没有办法增加输入缓冲区?

GVillani82 表明他拥有一些严肃的 Google-Fu;来自评论:

"Maybe related with this https://issuetracker.google.com/issues/123307358 ?"

表明这可能是运行时 27 及之前的错误。据推测它在以后的版本中已修复,尽管错误报告没有说明 哪个 版本。


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

基本上,在 Java 中,有两种方法可以执行 增量加密 。一种是简单地使用许多 Cipher.update 方法中的一种,并从缓冲区提供文本(并注意密文的 Cipher.update returns 部分,当它可用时)。然后你需要使用doFinal()方法完成加密。

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

使用 doFinal 使用输入和输出缓冲区 (ByteBuffer) 似乎仍会触发错误,因此无法正常工作。