sqljdbc4.jar - 无法连接到 MSSQL 服务器实例 - SSL 错误?

我正在使用此代码在 Ubuntu 机器上使用 sqljdbc4.jar 从 OpenJDK1.8 连接到 MSSQL 2012 实例:

public static DataSource getMsSqlPoolSource(String server,String database,String user,String password) throws ClassnotFoundException {
    Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");

    String connectionString = "jdbc:sqlserver://" + server + ";databaseName=" + database + ";sendStringParametersAsUnicode=false;";
    System.out.println("Connection String for MSSQL is:: " + connectionString);
    org.apache.commons.dbcp2.ConnectionFactory factory = new DriverManagerConnectionFactory(connectionString,user,password);
    PoolableConnectionFactory poolFactory = new PoolableConnectionFactory(factory,null);
    ObjectPool<PoolableConnection> connectionPool = new GenericObjectPool<>(poolFactory);
    poolFactory.setPool(connectionPool);
    PoolingDataSource<PoolableConnection> dataSource = new PoolingDataSource<>(connectionPool);
    return dataSource;
}

这已经工作了三年,直到今天。

如果我现在尝试从与过去三年相同的 Ubuntu 机器连接到相同的 MSSQL 2012 实例,则会出现异常:

2021-07-31 10:01:07.125 ERROR vsCallLogSyncOnVerinet - SQL ERROR:: 1jyg0yezlh46 - invalid database address: jdbc:sqlserver://172.16.1.244;databaseName=my_DB;sendStringParametersAsUnicode=false;
Security providers: [SUN version 1.8,SunRsaSign version 1.8,SunEC version 1.8,SunJSSE version 1.8,SunJCE version 1.8,SunJGSS version 1.8,SunSASL version 1.8,XMLDSig version 1.8,SunPCSC version 1.8]
SSLContext provider info: Sun JSSE provider(pkcs12,SunX509/PKIX key/trust factories,SSLv3/TLSv1/TLSv1.1/TLSv1.2/TLSv1.3)
SSLContext provider services:
[SunJSSE: KeyFactory.RSA -> sun.security.rsa.RSAKeyFactory$Legacy
  aliases: [1.2.840.113549.1.1,OID.1.2.840.113549.1.1],SunJSSE: KeyPairGenerator.RSA -> sun.security.rsa.RSAKeyPairGenerator$Legacy
  aliases: [1.2.840.113549.1.1,SunJSSE: Signature.MD2withRSA -> sun.security.rsa.RSASignature$MD2withRSA
  aliases: [1.2.840.113549.1.1.2,OID.1.2.840.113549.1.1.2],SunJSSE: Signature.MD5withRSA -> sun.security.rsa.RSASignature$MD5withRSA
  aliases: [1.2.840.113549.1.1.4,OID.1.2.840.113549.1.1.4],SunJSSE: Signature.SHA1withRSA -> sun.security.rsa.RSASignature$SHA1withRSA
  aliases: [1.2.840.113549.1.1.5,OID.1.2.840.113549.1.1.5,1.3.14.3.2.29,OID.1.3.14.3.2.29],SunJSSE: Signature.MD5andSHA1withRSA -> sun.security.ssl.RSASignature,SunJSSE: KeyManagerFactory.SunX509 -> sun.security.ssl.KeyManagerFactoryImpl$SunX509,SunJSSE: KeyManagerFactory.NewSunX509 -> sun.security.ssl.KeyManagerFactoryImpl$X509
  aliases: [PKIX],SunJSSE: TrustManagerFactory.SunX509 -> sun.security.ssl.TrustManagerFactoryImpl$SimpleFactory,SunJSSE: TrustManagerFactory.PKIX -> sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory
  aliases: [SunPKIX,X509,X.509],SunJSSE: SSLContext.TLSv1 -> sun.security.ssl.SSLContextImpl$TLS10Context
  aliases: [SSLv3],SunJSSE: SSLContext.TLSv1.1 -> sun.security.ssl.SSLContextImpl$TLS11Context,SunJSSE: SSLContext.TLSv1.2 -> sun.security.ssl.SSLContextImpl$TLS12Context,SunJSSE: SSLContext.TLSv1.3 -> sun.security.ssl.SSLContextImpl$TLS13Context,SunJSSE: SSLContext.TLS -> sun.security.ssl.SSLContextImpl$TLSContext
  aliases: [SSL],SunJSSE: SSLContext.Default -> sun.security.ssl.SSLContextImpl$DefaultSSLContext,SunJSSE: KeyStore.pkcs12 -> sun.security.pkcs12.pkcs12KeyStore
]
java.ext.dirs: /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext:/usr/java/packages/lib/ext

我最近向 OpenJDK1.8 证书存储中添加了一些证书,用于与本地 B 类上的直接 by-ip 连接无关的两个域,我通过 B 类 LAN 连接到本地 MSSQL 实例。

为什么 MSSQL JDBC 驱动程序突然导致明显的涉及证书的异常,并拒绝连接?

我不希望 JDBC 驱动程序使用我添加的任何证书,它必须正常运行并忽略它们?

我有另一台 Ubuntu 机器使用相同的 JDK 版本和相同的 JDBC 驱动程序,以及包含我的应用程序的相同 JAR,它在 OpenJDK1.8 证书存储中没有任何类型的用户添加的证书,并且它可以连接到同一个 MSSQL 服务器,使用 JDBC 驱动程序,使用相同的连接字符串,没问题。

为什么要为我从 Java 应用程序连接到的 Internet 上的不相关域添加 SSL 证书,现在显然会导致该应用程序中的 MSSQL Java JDBC 驱动程序尝试使用来自 OpenJDK1.8 证书库的随机 SSL 证书连接到本地 by-ip B 类网络上的本地 MSSQSL 服务器?

证书是这样添加的:

/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/keytool -trustcacerts -keystore /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts -storepass changeit -noprompt -importcert -alias lets-encrypt-x3-cross-signed -file lets-encrypt-x3-cross-signed.der

/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/keytool -trustcacerts -keystore /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts -storepass changeit -noprompt -importcert -alias lets-encrypt-x3-cross-signed2 -file isrg-root-x1-cross-signed.der

/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/keytool -trustcacerts -keystore /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts -storepass changeit -noprompt -importcert -alias lets-encrypt-x3-cross-signed3 -file lets-encrypt-r3.der

编辑:设法确定上面添加的 SSH 证书不是问题 - 如果我将它们从信任库中删除,问题仍然存在,与上述 JDBC 连接完全一样。因此加载的 SSH 证书对 JDBC 连接问题没有影响 e。 G。连接尝试作为无效的数据库地址返回。

zqp19880915 回答:sqljdbc4.jar - 无法连接到 MSSQL 服务器实例 - SSL 错误?

这是在 Mark Rotteveel 和 AlwaysLearning 的帮助下解决的。

这与我加载到 OpenJDK1.8 信任库中的 SSL 证书无关。

问题是三重的。

首先,在我的 Netbeans 11 项目中,在“Dependencies”文件夹中,我有一个名为

的 jar

MSSQL-4.0.jar

显然是由项目的前任开发人员手动放置在那里的。

我删除了这个文件 - 我不知道正在使用哪个驱动程序,因为我有一个上面详述的 maven 工件,也用于 MSSQL JDBC 驱动程序。

其次,AlwaysLearning 好心地指出,我与 MSSQL 的连接异常是指 SQLLite(不是 MSSQL),并且无效的数据库地址异常是由 SQLLite 驱动程序报告的,而不是 MSSQL 驱动程序。

核心问题是,由于某种原因,当我尝试使用上述源代码连接到 MSSQL 时,MSSQL JDBC 驱动程序正在尝试通过 SQLLite 连接到 MSSQL。

这就是为什么我总是收到

java.sql.SQLException: invalid database address:jdbc:sqlserver://172.17.12.14;databaseName=DB;sendStringParametersAsUnicode=false;

当然,SQLLite 连接协议永远不会在 MSSQL 服务器上工作...

第三,连接尝试到 MSSQL 的异常然后更改为指的是 MSSQL 服务器使用太旧的 TLS 加密进行连接的事实,而我的客户在 JDBC 端拒绝了这一点 - 见上文。 Mark Rotteveel 随后协助编辑文件

/etc/java-8-openjdk/security/java.security

在我的 Ubuntu 20.11 LTS OpenJKD1.8 安装上降低了 TLS 的安全性,以便我的 OpenJDK1.8 实例将允许 TLS 加密级别,这是我试图连接到的相当旧的 MSSQL 实例所需要的。

在 /etc/java-8-openjdk/security/java.security 我改变了行

jdk.tls.disabledAlgorithms=SSLv3,TLSv1,TLSv1.1,RC4,DES,MD5withRSA,\
    DH keySize < 1024,EC keySize < 224,3DES_EDE_CBC,anon,NULL,\
    include jdk.disabled.namedCurves

jdk.tls.disabledAlgorithms=SSLv3,\
    include jdk.disabled.namedCurves

总而言之,在从我的 NetBeans 项目的“Dependencies”文件夹中删除虚假的 MSSQL-4.0.jar 之后,我还注释掉了 SQLLite 的 Maven 工件(因为它不再在我的项目中使用,并且是一个遗留库)。一旦 Maven 在下一次编译中删除了 SQLLite 库,并且我按照上面的详细说明编辑了 java.security 文件,生成的 .JAR 就能够从我的 Ubuntu 机器连接到 MSSQL 服务器,之后我降低了 / etc/java-8-openjdk/security/java.security 并使用 OpenJDK1.8 安装在 Ubuntu 机器上重新启动我的应用程序。

这是因为 MSSQL JDBC 驱动程序现在使用“真正的”MSSQL 协议尝试从我的 Ubuntu 机器连接到 MSSQL 服务器,而不是尝试使用 SQLLite 协议连接到 MSSQL 服务器,-AND-在对 java.security 进行更改后,JDBC 驱动程序被允许与 MSSQL 服务器通信“足够旧”的 TLS 版本。

希望这对其他人有所帮助。

斯蒂芬

本文链接:https://www.f2er.com/6113.html

大家都在问