1

Oracle JRE 7 で実行され、標準の Microsoft jdbc ドライバーを使用して Microsoft SQL Server とデータを交換するアプリケーションがあります。

このアプリケーションが展開されている会社がデータベースを SQL Server 2017 に更新し、TLSv1.2 より低いすべての TLS プロトコルを無効にすることを決定するまで、問題なく機能していました。SQL Server に接続しようとすると、アプリケーションで次のエラーが発生します。

com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. 
Error: "SQL Server did not return a response. The connection has been closed. ClientConnectionId:5892fb2f-67c4-45f5-a01d-cc7c1db8f69e".
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1667)
    at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1668)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1323)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:991)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:827)
    at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1012)
    at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:131)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:156)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:145)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:200)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1086)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1073)
    at com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:44)
    at com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1810)
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:648)
Caused by: java.io.IOException: SQL Server did not return a response. The connection has been closed. ClientConnectionId:5892fb2f-67c4-45f5-a01d-cc7c1db8f69e
    at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.ensureSSLPayload(IOBuffer.java:651)
    at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.readInternal(IOBuffer.java:708)
    at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.read(IOBuffer.java:700)
    at com.microsoft.sqlserver.jdbc.TDSChannel$ProxyInputStream.readInternal(IOBuffer.java:895)
    at com.microsoft.sqlserver.jdbc.TDSChannel$ProxyInputStream.read(IOBuffer.java:883)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
    at sun.security.ssl.InputRecord.read(InputRecord.java:480)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
    at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1618)
    ... 13 more

-Djavax.net.debug=ssl:handshake:verbose JVM オプションを使用して SSL ハンドシェイク ロギングを有効にしましたが、jdbc ドライバーが TLSv1 を使用しようとしていることがわかります。

*** ClientHello, TLSv1

私はこのアプリケーションをサポートする開発者です。ソースがあり、変更を加えることができます。しばらくすると、このアプリケーションは JRE 8 に移植されますが、かなりの労力が必要になるため、現時点では回避策があるとよいでしょう。

解決策を探しているときに見つけたもの:

TLS 1.2 は Java 8 でサポートされていましたが、Java 7 ではサポートされていません
。 JRE を 1.7.0_131 に更新しています。ただし、131 アップデートは、Oracle Java サポート契約を結んでいる人のみが利用できます。Oracle JDK 7 の最新の無料アップデートは 1.7.0_80 です。

https://social.technet.microsoft.com/Forums/en-US/fb80c86c-97a2-4e35-b998-1030a5c77580/does-jdbc-driver-support-for-tlsv12-with-jre-17
正確に私のようです問題。1 人のユーザーが解決策を見つけましたが、IBM JDK でしか機能しません。

4

1 に答える 1

5

内部jreクラスを使用してTLS 1.2の使用を強制する、醜いハキーなソリューションになりました。jdbc 接続を確立する前に、この関数を呼び出します。

import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import javax.net.ssl.SSLContextSpi;
import sun.security.jca.GetInstance;
import sun.security.jca.ProviderList;
import sun.security.jca.Providers;

public static void enableTLSv12ForMssqlJdbc() throws NoSuchAlgorithmException
{
    ProviderList providerList = Providers.getProviderList();
    GetInstance.Instance instance = GetInstance.getInstance("SSLContext", SSLContextSpi.class, "TLS");
    for (Provider provider : providerList.providers())
    {
        if (provider == instance.provider)
        {
            provider.put("Alg.Alias.SSLContext.TLS", "TLSv1.2");
        }
    }
}

jdbc ドライバーが TLSv1.2 を使用し、SQL Server 2017 に正常に接続することがわかりました。

*** ClientHello, TLSv1.2
于 2018-06-01T18:05:32.477 に答える