【发布时间】:2012-11-05 09:12:19
【问题描述】:
我的团队需要开发一种解决方案,在用 Java 编写的 Android 应用程序的上下文中加密二进制数据(存储为 byte[])。加密后的数据会以多种方式传输和存储,期间不能排除数据损坏的可能。最终,另一个 Android 应用程序(同样是用 Java 编写的)必须解密数据。
已经决定加密算法必须是 AES,密钥为 256 位。 但是,我想就我们应该使用哪种 AES 实现和/或“模式”做出明智的决定。我读过一种叫做 GCM 模式的东西,我们已经用它做了一些测试(使用 BouncyCastle/SpongyCastle),但我并不完全清楚 AES-GCM 到底是做什么用的,以及与普通模式相比它“购买”我们的是什么AES - 以及是否需要考虑任何权衡。
以下是我们的顾虑/要求/问题列表:
填充:我们需要加密的数据并不总是 128 位的倍数,因此 AES 实现/模式应该添加填充,但仅在必要时。 我的印象是,一个简单的 AES 实现,比如
javax.crypto.Cipher提供的,不会这样做,但最初的测试表明它确实如此。所以我猜测填充要求本身并没有理由求助于 GCM 而不是“普通”AES。对吗?身份验证:我们需要一种万无一失的方法来检测是否发生了数据损坏。但是,理想情况下,我们还希望检测何时尝试使用不正确的密钥进行解密。因此,我们希望能够区分这两种情况。我最终考虑 GCM 的原因是因为 Stackoverflow question,其中一位响应者似乎暗示使用 AES-GCM 可以进行这种区分,尽管他没有提供详细的解释(更不用说代码了) )。
最小化开销:我们需要限制加密数据的存储和传输开销。因此,我们希望了解特定 AES 实现/模式的选择是否以及在多大程度上会影响开销。
加密/解密性能:虽然这不是主要问题,但我们想知道特定 AES 实现/模式的选择在多大程度上影响加密和解密性能,无论是在以下方面CPU 时间和内存占用。
提前感谢您提供任何建议、说明和/或代码示例。
编辑: delnan 有用地指出没有“普通 AES”之类的东西。所以澄清一下,我的意思是使用 Java 的内置 AES 支持。
像这样:Cipher localCipher = Cipher.getInstance("AES");
【问题讨论】:
-
什么是“普通”AES?除非您只处理 256 位数据。如果你有更多的数据,你必须使用 some 模式。也许您的库默认选择一种模式(据我所知,许多库在这里做出了相当不安全的选择)。所以你应该检查当你使用“普通”AES时实际使用的是哪种模式。
-
感谢@delnan 的评论,我进行了编辑以澄清我的意思。
标签: android encryption aes bouncycastle aes-gcm