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

2022-01-10 00:00:00 cpu cryptography aes java jvm-hotspot

Oracle 在 AES-NI 方面对 Java 8 有这样的看法:

Oracle has this to say about Java 8 with regards to AES-NI:

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

Hardware intrinsics were added to use Advanced Encryption Standard (AES). The UseAES and UseAESIntrinsics flags are available to enable the hardware-based AES intrinsics for Intel hardware. The hardware must be 2010 or newer Westmere hardware. For example, to enable hardware AES, use the following flags:

-XX:+UseAES -XX:+UseAESIntrinsics

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

To disable hardware AES use the following flags:

-XX:-UseAES -XX:-UseAESIntrinsics

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

But it does not indicate if AES intrinsics are enabled by default (for processors that support it). So the question is simple: if the processor supports AES-NI, are AES intrinsics used?

额外问题:有什么方法可以测试是否使用了 AES-NI?我想您可以根据性能进行猜测,但这不是最佳或肯定的测试方式.

Bonus question: is there any way to test if AES-NI is being used? I guess you can guess based on performance, but that's not an optimal or sure fire way of testing.

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

For readerS that are not familiar with AES-NI intrinsics: it's replacing byte code with pre-compiled machine code, using the AES-NI instruction set. This happens by the JVM, so it does not show up in the API of the Java runtime or bytecode.

推荐答案

该标志默认为true,如果检测失败将设置为false,因此可以简单地使用+PrintFlagsFinal来查看是否使用:

The flag has a default of true and it will be set to false if the detection fails, so you can simply use +PrintFlagsFinal to see if it is used:

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

My Laptop without AES-NI:

C:>"C:Program FilesJavajdk1.7.0_51injava" -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:

Same on Desktop with AES-NI:

C:>"C:Program FilesJavajdk7injava" -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)Javajre7injava" -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.

So, it works for both x64 and i686 (WOW64) with recent Java 7. The feature was introduced with https://bugs.openjdk.java.net/browse/JDK-7184394 and backported to 7u40 and 7u45.

重要提示:AES-NI 可能仅在服务器虚拟机上可用.

Important: AES-NI may only be available on the server VM.

在提交错误报告后,Oracle 承认了这一点.当他们创建引入它的 Java 8 的功能列表时,这条重要的信息丢失了(后来它也被向后移植到 7).服务器 VM 可以通过在 javajavaw 命令行上提供 -server 选项来显式选择.

This was acknowledged by Oracle after a bug report was filed. This vital piece of information was missing when they created the featues list of Java 8 where it was introduced (it later got backported to 7 as well). The server VM can be explicitly choosen by providing the -server option on the java or javaw command line.

相关文章