こんにちは、Japan Developer Support Core チームの高橋です。今回は SQL Server への接続の問題のうち、Java アプリケーションから Microsoft JDBC Driver for SQL Server を使用して SQL Server に接続する際の、特に TLS (Transport Layer Security) に関連する設定に起因して接続エラーとなる事象のトラブルシューティング手順などについて解説します。
この記事は以下のような状況にある方を対象としています:
- Microsoft JDBC Driver for SQL Server を使用した接続が 100% 失敗する。
- 初めて環境を構成した、または設定を変更してからエラーが発生するようになった。
- Java アプリケーション実行環境の TLS バージョンを 1.2 に限定するなどの設定変更を行おうとしている。
対象となるエラー
本記事では、TCP/IP によるセッションは確立できたものの、認証の過程でエラーとなるケースを対象とします。以下のようなエラーメッセージが表示される場合が該当します:
ドライバーが Secure Sockets Layer (SSL) 暗号化を使用して SQL Server へのセキュリティで保護された接続を確立できませんでした
このエラーメッセージに加えて、通常は根本的な原因を示す追加のメッセージ(例: "SQL Server が応答を返しませんでした。接続が閉じられました。" など)が続いて表示されます。これらの追加メッセージは原因特定に重要な情報となり、この記事に記載の問題とは別のトラブルシューティングが必要となることもありますので、必ず確認してください。
エラーが発生する理由
SQL Server への接続確立の処理では、以下の順序で処理が行われます:
- TCP/IP によるセッションの確立
- 認証処理
- データベースへのアクセス
2 ステップ目の認証処理で使用される資格情報(SQL 認証におけるパスワードなど)は、セキュリティ保護のために必ず暗号化されます。これは SQL Server 側で暗号化を強制しているかどうかに関係なく行われます。上記のエラーは、この認証処理における主に暗号化処理過程で問題が発生したことを示しています。例えばクライアントとサーバーのそれぞれで使用可能な TLS バージョンが異なることが主な原因の 1 つです。
トラブルシューティング手順
クライアント側とサーバー側のそれぞれが同じ TLS バージョンを使用できない限りは SQL Server への接続は失敗します。つまり、このような不一致がない状態とすることが重要です。
そこで、以下の 1 ~ 5 の手順に従って TLS 関連の設定を確認しましょう。その上で、不一致となるような環境構成となっている場合には、適宜変更を行い、問題が解消するか確認しましょう。
1. 各種バージョンの確認
使用している製品がサポートされているバージョンであることを確認しましょう。
1.1 OS バージョン
クライアント側とサーバー側の両方の OS バージョンがサポートされている OS であることを確認しましょう。もしサポートされていない OS バージョンの場合には OS アップグレード、別の環境の利用などを検討しましょう。
製品およびサービスのライフサイクル情報の検索 - Windows
1.2 SQL Server バージョン
SQL Server のバージョンがサポートされているバージョンであることを確認しましょう。もしサポートされていない SQL Server バージョンの場合には OS アップグレード、別の環境の利用などを検討しましょう。
製品およびサービスのライフサイクル情報の検索 - SQL Server
1.3 Java ディストリビューション/バージョン
TLS バージョンの既定の設定がディストリビューションやバージョンによって異なる場合があります。そのため、使用している JDK/JRE のディストリビューション(Oracle、OpenJDK、IBM、Adoptium など)とバージョンを確認しておきましょう。
1.4 Microsoft JDBC Driver for SQL Server バージョン
使用している JDBC ドライバーのバージョンを確認しましょう。サポートを終了している古いバージョンでは TLS 1.1 以降のバージョンがサポートされていない可能性があります。
JDBC ドライバーのバージョン
.jar ファイルの名前に含まれています。(例:mssql-jdbc-12.2.0.jre11.jar)サポートされているバージョン
Microsoft SQL Server 用 JDBC Driver のサポート表 で確認できます。
その上で、サポートされていない古いバージョンを使用している場合は、最新のサポートされているバージョンへのアップグレードを検討しましょう。
2. Java における TLS 有効化設定の確認
Java では、java.security ファイル内の jdk.tls.disabledAlgorithms 設定で TLS バージョンの有効/無効を制御しています。使用したい TLS バージョンや暗号スイートが無効になっていないか、無効になっている場合にはその設定を削除して問題が解消するかを確認します。
Java 向け TLS 設定ファイルの場所
java.security ファイルは、通常以下の場所にあります:
$JAVA_HOME/conf/security/java.security(Java 9 以降)$JAVA_HOME/lib/security/java.security(Java 8 以前)
Java 向け TLS 設定の確認方法
java.securityファイルを任意のテキストエディターで開きます。jdk.tls.disabledAlgorithmsの設定を探します。- 設定が見つかったら、使用したい TLS バージョン(例: TLSv1.2)が無効化されていないか確認します。
- 暗号スイートについても OS で使用可能な暗号スイートと一致するアルゴリズムが含まれているか確認します。
例えば、以下のような設定の場合、TLSv1 と TLSv1.1 が無効化されていることを示します。:
1 | jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, ... |
仮に古い環境との組み合わせにより TLS バージョン 1.0 が必要な場合には、この TLSv1, を設定から取り除いて保存します。これを利用する Java ランタイム環境からの SQL Server への接続において TLS 1.0 も使用可能となります。
3. OS における TLS 設定の確認
Java アプリケーションは Java のセキュリティ設定を使用しますが、OS 側で TLS バージョンが制限されている場合は、その制限が適用されます。また、SQL Server も OS の TLS 設定を使用します。そのため、OS の TLS バージョンの設定も確認しましょう。
Windows の TLS 設定の確認
Windows では、レジストリで TLS バージョンの有効/無効を設定します。
- レジストリエディタを開きます。
- 以下のパスを確認します:
- クライアント側:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client - サーバー側:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server
- クライアント側:
Enabledの値が1、DisabledByDefaultの値が0であることを確認します。
詳細については、トランスポート層セキュリティ (TLS) のレジストリ設定 に説明があります。
また、Windows のバージョンごとにサポートされる暗号スイートが異なります。こちらも詳細は公式ドキュメント TLS/SSL (Schannel SSP) の暗号スイート に説明があります。
Linux の TLS 設定の確認
Linux ディストリビューションによって設定方法が異なる可能性があります。使用しているディストリビューションのドキュメントを参照して、TLS 設定を確認してください。
4. SQL Server における暗号化強制設定の確認
SQL Server には通信の暗号化を強制する設定があります。暗号化が強制されている場合には追加の設定が必要となりますので、この設定についても確認しておきましょう。
なお、Azure SQL Database では暗号化が強制されます。
SQL Server の暗号化設定の確認方法
SQL Server Configuration Manager で以下を確認します:
- SQL Server Configuration Manager を開きます。
- SQL Server ネットワークの構成 > [インスタンス名] のプロトコル を選択します。
- 右側のペインを右クリックし、プロパティ を選択します。
- フラグ タブで ForceEncryption の設定を確認します。
SQL Server で暗号化が強制されている場合の対応
暗号化が強制されている場合は、以下のいずれかの対応が必要です:
- 証明書を信頼する設定: 接続文字列に
trustServerCertificate=trueを追加します。 - 証明書のインストール: サーバーの証明書をクライアント側のトラストストアにインポートします。
詳細については、接続を暗号化するために SQL Server データベース エンジンを構成する を参照し、適宜設定しましょう。
5. 接続文字列における TLS バージョンの設定
Microsoft JDBC Driver for SQL Server では、接続プロパティ sslProtocol を使用して、認証時の暗号化に使用する TLS バージョンを明示的に指定できます。そこで、設定されているかどうか、設定されていない場合には追加設定することにより問題が解消するかどうか、設定されている場合には使用したい TLS バージョンであるかを確認します。
接続文字列での TLS バージョン設定例
1 | String connectionUrl = "jdbc:sqlserver://localhost:1433;" + |
注意事項
指定する文字列で使用される TLS バージョンは Java ディストリビューションによって異なります。
- TLS: Oracle JVM では TLS 1.0 ~ 1.2、IBM JVM では TLS 1.0 のみなど。
詳細については、SSLProtocol および 接続プロパティの設定 に説明があります。
さらなる調査が必要な場合
上記のトラブルシューティングを実施しても問題が解決しない場合は、マイクロソフト サポートまでお問い合わせください。お問い合わせの際には、以下の情報をご準備いただくとスムーズに調査を進めることができます。
なお、事前に JDBC の構成とトラブルシューティング に記載の内容も確認しておきましょう。思わぬ設定漏れに気づくことや、サンプルによる動作確認による問題箇所の最小化がその後の調査をスムーズとすることもあります。
準備していただきたい情報
環境情報
- クライアント OS のバージョン
- サーバー OS のバージョン
- SQL Server のバージョンとエディション
- Java ディストリビューションとバージョン
- Microsoft JDBC Driver for SQL Server のバージョン
設定情報
- 接続文字列(パスワードは除く、マスクするなど)
java.securityファイルのjdk.tls.disabledAlgorithms設定- Windows の場合: TLS に関するレジストリ設定 (エクスポートしたファイル)
- SQL Server の暗号化設定(ForceEncryption の値)
エラー情報
- 完全なエラーメッセージとスタックトレース
- エラーが発生するタイミング(常に/間欠的)
トレース
トレースの取得についてもブログで紹介していますのでそちらを参考に取得しましょう。 Microsoft JDBC Driver for SQL Server のトレース取得方法まとめ- JDBC ドライバーのトレース: JDBC ドライバーの処理内容を記録
- Java SSL/TLS デバッグトレース: Java の SSL/TLS 通信の詳細を記録
実施済みのトラブルシューティング内容
- 本記事の手順のうち、どの手順を実施したか
- 実施した結果、どのような状態であったか
まとめ
Microsoft JDBC Driver for SQL Server を使用した接続における TLS 関連のエラーは、主に以下の要因で発生します:
- 各製品のバージョンのサポート状況
- Java における TLS バージョンの無効化設定
- OS における TLS バージョンの制限
- SQL Server の暗号化強制設定と証明書の信頼関係
- 接続文字列での TLS バージョン設定
本記事で紹介したトラブルシューティング手順に従って、設定を確認・変更することで、問題の解決の参考になるようでしたら幸いです。またそれでも解決しない場合は、スムーズな対処のためにもご紹介した各種情報を取得した上で、マイクロソフト サポートまでお問い合わせいただけると助かります。
本ブログの内容は弊社の公式見解として保証されるものではなく、開発・運用時の参考情報としてご活用いただくことを目的としています。もし公式な見解が必要な場合は、弊社ドキュメント (https://learn.microsoft.com や https://support.microsoft.com) をご参照いただくか、もしくは私共サポートまでお問い合わせください。