在Android中,“AES”密码的含义是什么?

8

我继承了使用以下密码的Android代码:

ks = new SecretKeySpec(key, "AES");
ciph = Cipher.getInstance("AES");

由于仅给出“AES”,我不知道密钥大小、模式和填充方式是什么。我查阅了Bouncy Castle*的文档,但无法找到描述“AES”实例的地方。如果可以的话,我想使用更明确的实例描述(例如“AES/ECB/PCKS5Padding”)。

有人知道这个实例的密钥大小、模式和填充方式吗?

谢谢!

*我读到Android将Bouncy Castle作为其默认提供程序,但我没有在官方网站上找到相关信息,所以这可能是一个没有帮助的假设。


1
请参阅http://stackoverflow.com/a/13209169/90322。 - Jeff Ferland
1
一旦你弄清楚了默认设置是什么,就要更正代码,明确请求模式和填充。让提供程序特定的默认值是愚蠢的,Sun不应该允许这种情况发生。 - President James K. Polk
@ewanm89:我不同意。密码学标准的重点不仅在于安全性,还在于互操作性。具有特定提供商默认值会阻碍互操作性。如果它们必须具有默认值,则应该是提供程序无关的,并且应该只是块密码的CBC与PKCS5/7填充。对于String.getBytes()和相应的new String(byte[])构造函数也是如此。这些默认值是特定于平台的。这是一个大错误,并将永远成为相同错误的原因。 - President James K. Polk
顺便说一下,除非你正在加密对称密钥,或者在包装库中实现另一种模式,否则你绝不应该使用ECB。请至少使用“CBC/PKCS5Padding”,或者如果可用,“GCM/NoPadding”。 - Maarten Bodewes
1
@ewanm89,我不知道你在这里想要实现什么。我只是在评论中警告用户不要使用ECB模式加密,因为一般来说ECB模式加密不适合使用。然后我收到了你的一堆评论,其中大部分都是可疑的,并且只显示了你对密码学的无知。为什么不停止呢?提示:192位AES密钥不是2的幂,512位AES密钥不存在。 - Maarten Bodewes
显示剩余6条评论
2个回答

5

根据Oracle文档的规定,Java默认使用"AES/ECB/PKCS5Padding"

If no mode or padding is specified, provider-specific default values for the mode and padding scheme are used. For example, the SunJCE provider uses ECB as the default mode, and PKCS5Padding as the default padding scheme for DES, DES-EDE and Blowfish ciphers. This means that in the case of the SunJCE provider:

Cipher c1 = Cipher.getInstance("DES/ECB/PKCS5Padding"); and
Cipher c1 = Cipher.getInstance("DES"); are equivalent statements.
请参考Oracle文档中的创建Cipher对象。我自己使用调试器进行了检查,至少对于Android 4.0而言,Android默认使用相同的加密和填充模式(如预期所示)。在使用单个(值为00)字节的默认提供程序时,输出结果是一个填充的明文,其十六进制值为000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F。这显然是PKCS#5填充,或者更准确地说是与16字节块密码相同的PKCS#7填充
理论上讲,任何提供程序都可以有不同于默认的"SunJCE"提供程序的默认设置。但是,这会破坏那些假设使用Oracle / OpenJDK默认设置的应用程序。
强烈建议指定包括模式和填充在内的整个字符串,而不要依赖默认设置来进行加密算法(除了SecureRandom,通常不建议指定算法)。

1
有趣的是,文档中提到的内容如此陈旧,以至于没有提到2001年推出的AES。 - President James K. Polk
被选为正确答案,因为提供了文档和实际测试结果。感谢您的努力! - bradreaves

1
据我所知,在Java中,AES代表使用ECB模式无填充。我认为在Android上也是一样的。我建议您在Android上运行一个简单的测试,加密一些内容,然后使用Java或Android中的AES/ECB/NoPadding进行解密。此外,如果您在该应用程序中没有看到任何IV,则需要指向另一个方向。

3
刚刚在安卓调试器中分析了一个实例,确认默认情况下采用ECB模式且没有填充。 - ewanm89
1
Sun/Oracle JDK将默认使用“PKCS5Padding”,如果Android不遵循相同的标准,我会非常惊讶。你是如何测试的?因为据我所知,“Cipher”对象本身并不返回任何答案。 - Maarten Bodewes
@owlstead:在运行Oracle Java 1.6的Eclipse调试器中,我可以看到Cipher对象的非公共字段。<object>.spi.core.padding字段是com.sun.sun.crypto.provider.PKCS5Padding类的一个实例,证实了你的说法。我想在Android上也是类似的情况。 - President James K. Polk
是的,如果启用填充提供程序,则在至少在运行于Android模拟器中的Bouncy Castle中使用它作为填充提供程序。此外,还有一个名为padding的第二个布尔字段,其值设置为false。 - ewanm89
在ECB模式下,它必须有一些填充,所以我不确定它到底在做什么,但是它将那个填充字段设置为false。不幸的是,初始化实例与加密某些内容,解密后又不触及填充并查看它实际上执行了什么是迥然不同的。 - ewanm89

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接