エラーメッセージ
No subject alternative names present
別の表記
- java.security.cert.CertificateException: No subject alternative names present
JDK 21 以降では、例外のテキストの先頭に「(certificate_unknown) 」が付きます。DNS のホスト名の場合、SAN のない証明書でも、Java ではコモンネームを通じて一致することがあります。ほかのクライアント(Go、Chrome)は、こうした証明書を一律に拒否します。
Java (JSSE HostnameChecker) — certificate without a SAN extension, URL host is an IP address
このエラーの意味
サーバーの証明書にはサブジェクト代替名拡張がまったくなく、クライアントは IP アドレスで接続しました。IP アドレスに対して、Java は IP SAN エントリを必須とし、コモンネームへのフォールバックは一切行いません。そのため SAN 拡張がなければ、比較する対象が何もありません。古いスクリプトで CN だけを入れて生成した証明書で典型的に起こる結果です。
発生する理由
subjectAltName なしで証明書が作成された
よくある-addext subjectAltName を付けない openssl req -x509、-ext SAN を付けない古い keytool コマンド、アプライアンスが生成した証明書が該当します。
IP アドレスがコモンネームに入れられている
よくあるCN=10.0.0.5 は正しく見えますが、IP アドレスの照合では無視されます。有効なのは IP SAN エントリだけです。
レガシーな PKI ツールやテンプレート
ときどきSAN が必須になる以前に作られた社内 CA のテンプレートが、CN だけの証明書を発行し続けています。
修正方法
- 1.
SAN 拡張がないことを確認する
サブジェクトと subjectAltName を表示してください。SAN が出力されなければ、証明書を再発行する必要があります。
bash openssl x509 -in server.pem -noout -subject -ext subjectAltName # "No extensions in certificate" / no SAN output -> the certificate must be reissued - 2.
subjectAltName を含めて再発行する
DNS エントリと、必要に応じて IP エントリを追加してください。CN は表示用にだけ残してください。
bash openssl req -new -key server.key -out server.csr -subj "/CN=api.example.com" \ -addext "subjectAltName=DNS:api.example.com,IP:10.0.0.5" # keytool (Java keystores) keytool -genkeypair -alias server -keyalg EC -groupname secp256r1 -dname "CN=api.example.com" \ -ext "SAN=dns:api.example.com,ip:10.0.0.5" -keystore server.p12 -storepass changeit