AR ホームベーカリー

オイラのアウトプット用ホームベーカリー!

古めの java でメール送信に TLS1.2 を利用する

古めの java というか ColdFusion11 バンドルの jdk なんすけどね。

TLS1.2 だけ有効にしたいなら JVM 起動引数に -Dmail.smtp.ssl.protocols="TLSv1.2" と記載すればオッケー。

java 7 以前はわからねえんだよな……、どうなんだろう? という所からの調査方法含めて調べてみた。

TLS 1 と 1.1

上記だと TLSv1.2 が強制されてしまって、古い認証方式の所と接続できないので、結局は以下にするのが丸い。

-Dmail.smtp.ssl.protocols="TLSv1 TLSv1.1 TLSv1.2"

ちなみに複数指定する時は、カンマではなく空白で区切る必要があるとのこと。 たぶんおおよその java バージョンで共通だと思う。

mail.smtp.ssl.protocols

Specifies the SSL protocols that will be enabled for SSL connections. The property value is a whitespace separated list of tokens acceptable to the javax.net.ssl.SSLSocket.setEnabledProtocols method.

javaee.github.io

setEnabledProtocols で取得できるプロトコルが指定できる。 本記事の目的だと TLSv1.2 ですね。

getEnbaledProtocols

この接続に対して現在使用可能になっているプロトコルの名前を返します。

「(利用できるけど) 有効化されてないプロトコルは返却されない」と読める。

docs.oracle.com

バージョン的にサポートされている暗号化スイート全部取得するにはどうすりゃええんや、と思ってたら以下が存在する模様。

getCipherSuites

最初 getEnabledCipherSuites で取れる! と思ってたんだけど、これも上記の Protocols と同じで、現時点の接続で有効化されてるという縛りがつくのでダメー。

という訳でこちらを利用すれば良い模様。 しょうがねえコード書くか、と思ったら、既にやってる先達が居た。ありがてえありがてえ。

qiita.com

確認する方法

基本的に README の通りやれば、 javac あたりにパス通ってればなんとかなるはず。 記載の通り java8 で作成されてるとのことなので、バージョン違いだと動かないかもしれない。

github.com

git clone git@github.com:msakamoto-sf/java-jsse-cipher-suites-dump-demo.git
cd java-jsse-cipher-suites-dump-demo
./mvnw package
#=> コンパイルが始まる
java -jar target/java-jsse-cipher-suites-dump-demo-v201901.1.jar

TLSv1,default,TLS_DHE_DSS_WITH_AES_128_CBC_SHA
.
.
# snip #
.
.
TLSv1.2,supported,TLS_RSA_WITH_AES_256_GCM_SHA384

なるほどー。 今回は JVM に指定する引数が合っているか確認したいので、標準出力の内容を加工する。

java -jar target/java-jsse-cipher-suites-dump-demo-v201901.1.jar | awk -F '[,]' '{print $1}' | uniq -c
  56 TLSv1
  56 TLSv1.1
  84 TLSv1.2

重複していない変なやつもおらんので、この java 環境で利用できるすべての値を指定するには -Dmail.smtp.ssl.protocols="TLSv1 TLSv1.1 TLSv1.2" とすればよい、と判明した。

いやあ長かった。 java の標準オプションでこういうの調べるのあったりしねえのかな。

テストしたロケ地

結局 java7 以前がどうなのかわかってねえじゃねえか! って言われたらそれはそう。 そんな古い環境投げ捨てろとしか言えないし、自分に特大ブーメランが刺さってしまう (すでに刺さっている)。

java -version
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)

記法の違い

複数指定できるプロトコルバージョンあたりだと、あとは https.protocols が思いつくと思うけど、こいつは空白じゃなくてカンマ区切りなんですよね。

やはり慢心、パッケージ作者の見解の相違……。

その他

TLS 1.2 は OpenSSL 1.0.1 以降?らしいので、 Java 自体もそうだけど OpenSSL のバージョンも 0.9.8 とかだったらアップデートしないとダメだと思われる。

teratail.com