Java8でサポートしているTLS Cipher Suiteの比較調査

Java8でサポートしているTLS Cipher Suite について、OracleJDK / AdoptOpenJDK / Linux提供のOpenJDK 間で違いがあるか調査してみた。

## サポートしているTLS Cipher Suite 一覧を取得

以下のコマンドラインツールを作成して一覧を取得した。

- https://github.com/msakamoto-sf/java-jsse-cipher-suites-dump-demo

## 比較対象のOpenJDK8について

以下のOpenJDK8について上記ツールで一覧を取得した。

- Windows 64bit
  - OracleJDK : https://www.oracle.com/technetwork/java/javase/downloads/index.html
  - AdoptOpenJDK : https://adoptopenjdk.net/ (Hotspot版を使用)
- Linux 64bit (以下、いずれもAWS EC2で実験。AMIはそれぞれ公式のものを使用)
  - Amazon Linux 2 の標準リポジトリ提供
  - CentOS7 の標準リポジトリ提供
  - Ubuntu 18.04 Server の標準リポジトリ提供

バージョン詳細は以下の通り。

OracleJDK8 for Win64:

```
> java -version
java version "1.8.0_192"
Java(TM) SE Runtime Environment (build 1.8.0_192-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.192-b12, mixed mode)
```

AdoptOpenJDK8 for Win64:

```
> java -version
openjdk version "1.8.0_192"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_192-b12)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.192-b12, mixed mode)
```

CentOS7(64bit):

```
$ sudo yum install java-1.8.0-openjdk.x86_64
-> java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64 がインストールされた。

$ java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
```

Amazon Linux 2(64bit):

```
$ sudo yum install java-1.8.0-openjdk.x86_64
-> java-1.8.0-openjdk-1.8.0.191.b12-0.amzn2.x86_64 がインストールされた。

$ java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
```

Ubuntu 18.04 Bionic(64bit):

```
$ sudo apt update
$ sudo apt-get install openjdk-8-jdk
-> openjdk-8-jdk, 8u191-b12-0ubuntu0.18.04.1 がインストールされた。

$ java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-8u191-b12-0ubuntu0.18.04.1-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
```

※Ubuntu 18.04 になると、外部PPAを追加しないとJDK8をインストールできないような書き方をしている記事がいくつか見つかった。
しかし今回のケースでは、原因は不明だが apt update しただけで、 openjdk-8-jdk をインストールできた。(apt update前はlocationが見つからずインストールできなかった)

## 調査結果

各環境で以下のコマンド結果をテキストファイルにリダイレクトして保存した。

```
java -jar java-jsse-cipher-suites-dump-demo-v201901.1.jar
java -Djava.security.properties=java.security.crypto.policy-limited -jar java-jsse-cipher-suites-dump-demo-v201901.1.jar
java -Djava.security.properties=java.security.crypto.policy-unlimited -jar java-jsse-cipher-suites-dump-demo-v201901.1.jar
```

※出力結果については以下に保存：

https://github.com/msakamoto-sf/java-jsse-cipher-suites-dump-demo/tree/v201901.1/2019-01-14_result

それぞれでdiffを見てみたところ、以下の結果となった：

1. `crypto.policy` のカスタマイズが無いデフォルト状態と、 `unlimited` 指定の結果が同じ。
1. さらに上記結果が、調査対象のすべての環境で同一となった。
1. `limited` の結果も調査対象のすべての環境で同一となった。

よって以下のことが確認できたと思われる。

1. 最新のJDK8では、デフォルトが `crypto.policy=unlimited` となりセキュアな状態になっている。
1. OpenJDKをベースに Oracle/AdoptOpenJDK/LinuxディストリビューターがそれぞれビルドしたJDKでも、全て同じ Cipher Suite が利用できる。

当然といえば当然の話で、もともとJSSEについては 100% Pure Java で実装されていて、OpenJDKの方でソースが管理されている。
そのためOpenJDKから特にソースをいじらずビルドしたものであれば、どのビルドバイナリでも、同じ Cipher Suite が利用できる状態になっている。

「Oracle JDKでしか使えない Cipher Suite」という存在は可能性としてはありうるが、相互運用性やセキュリティが重要な昨今、Javaエコシステムでそのような存在が許容されるかと言われればまず難しいと思われる。
(Oracle JDKの有償ユーザしか使えない特別拡張、という可能性もあるが、OpenJDK側のエコシステムを前提とするのであればそれはスコープ外となる)

・・・というのを、「本当？本当だよね・・・？？」と若干前から気にはなってたので、今回簡単ながら試してみたところ、確かに差異は見られないことを確認できた。
より厳密に検証するなら、各プロトコルバージョン x 単一 cipher suite の組み合わせのサーバソケット実際に用意して、実際に接続成功するかを逐一チェックしていく必要があるが、今回はまぁそこまではいっか・・・ということで、SSLContextから見える範囲での差分検証にした。

とりあえず、SSL/TLSの Cipher Suite については以上で「OpenJDKベースのビルドならどこのベンダからのバイナリでも使える Cipher Suiteは一緒」ということを確認できたので、一安心。