AES-NI内在函数默认启用?

时间:2014-04-14 10:56:40

标签: java cryptography aes cpu jvm-hotspot

关于AES-NI,Oracle有关于Java 8的说法:

  

添加了硬件内在函数以使用高级加密标准   (AES)。 UseAES和UseAESIntrinsics标志可用于启用   基于硬件的英特尔硬件AES内在函数。硬件   必须是2010年或更新的Westmere硬件。例如,要启用   硬件AES,使用以下标志:

-XX:+UseAES -XX:+UseAESIntrinsics
     

要禁用硬件AES,请使用以下标志:

-XX:-UseAES -XX:-UseAESIntrinsics

但它并不表示默认情况下是否启用AES内在函数(对于支持它的处理器)。所以问题很简单:如果处理器支持AES-NI,是否使用了AES内在函数?

奖金问题:有没有办法测试是否使用AES-NI?我想你可以根据性能进行猜测,但这不是最佳或确定的测试方法。


对于不熟悉AES-NI内在函数的读者:它使用AES-NI指令集用预编译的机器代码替换字节代码。这是由JVM发生的,因此它不会出现在Java运行时或字节码的API中。

2 个答案:

答案 0 :(得分:32)

该标志的默认值为true,如果检测失败,它将被设置为false,因此您只需使用+ PrintFlagsFinal查看是否使用它:

我的笔记本电脑没有 AES-NI:

C:\>"C:\Program Files\Java\jdk1.7.0_51\bin\java" -XX:+PrintFlagsFinal -version | find "UseAES"
     bool UseAES                                    = false           {product}
     bool UseAESIntrinsics                          = false           {product}
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

桌面 AES-NI相同:

C:\>"C:\Program Files\Java\jdk7\bin\java" -XX:+PrintFlagsFinal -version | find "AES"
     bool UseAES                                    = true            {product}
     bool UseAESIntrinsics                          = true            {product}

java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

C:\>"C:\Program Files (x86)\Java\jre7\bin\java" -XX:+PrintFlagsFinal -version | find "AES"
     bool UseAES                                    = true            {product}
     bool UseAESIntrinsics                          = true            {product}

java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) Client VM (build 24.51-b03, mixed mode, sharing)

因此,它适用于最新Java 7的x64和i686(WOW64)。该功能随https://bugs.openjdk.java.net/browse/JDK-7184394一起引入,并向后移植到7u40和7u45。


重要提示:AES-NI可能仅在服务器VM 上可用。

Oracle在a bug report was filed之后承认了这一点。当他们创建引入它的Java 8的特征列表时,这个至关重要的信息就丢失了(后来它也被反向移植到7)。可以通过在-serverjava命令行上提供javaw选项来明确选择服务器VM。

答案 1 :(得分:4)

无法发表评论(愚蠢的SO规则要求超过50个学分!)。 This mailthread from openjdk表示,默认情况下会启用所有AES内在函数。虽然我不确定有多少Oracle核心VM代码与openjdk共享。 如果您阅读整个线程,他们还会讨论32位虚拟机上的挑战,这可能解释了您的第二次测试运行时遇到的问题。

  • 关于您的测试(抱歉,无法发表评论),您认为CPU的差异不会产生很大影响吗? Core i7是四核的,通常具有更好的时钟速度。不会有所作为吗?我想从21s(核心i5,32bitVM,AES-NI关闭)到8s(核心i7,64bitVM,AES-NI关闭)的转变是i5和i7之间的差异。
  • 从8s到3s的改进,虽然不是7折,但确实值得“Yipes'! :)
  • 关于检测机制 - 似乎并不是一种直截了当的方式。 JVM抛出一个警告" AES内在函数在这个CPU上不可用"如果您启用了标记,并且无法找到AES支持 - as per this bug report