Android:AEAD 密码的 CipherStream-API 慢得无法接受
Android: CipherStream-API for AEAD Ciphers inacceptable slow
我们有一个 android 应用程序,可以通过 HTTP-Streams 解密和加密大型(最多 100MB)文件。
因此,我们正在使用 CipherInputStreams
和 CipherOutputStreams
,这对 AES/CBC/PKCS7Padding
来说效果很好。我们最近切换到 AES/GCM/NoPadding
。现在加密和解密对于大约 50MB 的文件来说是慢得不能接受的。
调试 android 源代码,揭示问题:https://android.googlesource.com/platform/libcore/+/master/ojluni/src/main/java/javax/crypto/CipherInputStream.java#112
此方法有字节缓冲区 "oBuffer",它被 重新分配 并增加了 512 位,直到它可以容纳整个消息(见行:https://android.googlesource.com/platform/libcore/+/master/ojluni/src/main/java/javax/crypto/CipherInputStream.java#121)
我知道有关此方法的说明,其中指出在 AEAD 密码中必须缓冲整个消息。这是一个问题,因为我们不能将整个消息保存到内存缓冲区中。另一个问题是 oBuffer 不断被重新分配。
是否有将 GCM 与流媒体一起使用的解决方案API?
将文件拆分成多个部分并链接是适合您的解决方案。
假设您将文件分成 n
个部分。使用 AES-GCM 加密它们中的每一个并添加以下内容。加密前各部分前缀如下;
tag_0 = ''
for i from 1 to n
ciphertextBlock_i, tag_i = AES-GCM( i:n || tag_i-1 || plaintextBlock_i)
- 在每个零件前面加上零件号作为
i:n
- 在除第一个部分之外的每个部分前面加上前一部分的身份验证标记。
有了这些,你就有了一条解密后可以控制的链。可以检测、添加、删除。订单由您掌控,即使没有订单,您也可以发送。但是,您需要检查前缀。
你也可以
- 添加零件尺寸,
- 如果你害怕重放攻击,也加上加密时间。
我们有一个 android 应用程序,可以通过 HTTP-Streams 解密和加密大型(最多 100MB)文件。
因此,我们正在使用 CipherInputStreams
和 CipherOutputStreams
,这对 AES/CBC/PKCS7Padding
来说效果很好。我们最近切换到 AES/GCM/NoPadding
。现在加密和解密对于大约 50MB 的文件来说是慢得不能接受的。
调试 android 源代码,揭示问题:https://android.googlesource.com/platform/libcore/+/master/ojluni/src/main/java/javax/crypto/CipherInputStream.java#112
此方法有字节缓冲区 "oBuffer",它被 重新分配 并增加了 512 位,直到它可以容纳整个消息(见行:https://android.googlesource.com/platform/libcore/+/master/ojluni/src/main/java/javax/crypto/CipherInputStream.java#121)
我知道有关此方法的说明,其中指出在 AEAD 密码中必须缓冲整个消息。这是一个问题,因为我们不能将整个消息保存到内存缓冲区中。另一个问题是 oBuffer 不断被重新分配。
是否有将 GCM 与流媒体一起使用的解决方案API?
将文件拆分成多个部分并链接是适合您的解决方案。
假设您将文件分成 n
个部分。使用 AES-GCM 加密它们中的每一个并添加以下内容。加密前各部分前缀如下;
tag_0 = ''
for i from 1 to n
ciphertextBlock_i, tag_i = AES-GCM( i:n || tag_i-1 || plaintextBlock_i)
- 在每个零件前面加上零件号作为
i:n
- 在除第一个部分之外的每个部分前面加上前一部分的身份验证标记。
有了这些,你就有了一条解密后可以控制的链。可以检测、添加、删除。订单由您掌控,即使没有订单,您也可以发送。但是,您需要检查前缀。
你也可以
- 添加零件尺寸,
- 如果你害怕重放攻击,也加上加密时间。