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