当前位置:   article > 正文

java与Sql Server建立连接异常Could not generate DH keypair及Unsupported curveId: 29_jdbc unsupported curveld:29

jdbc unsupported curveld:29

前言

最近在工作中想完成一个java通过jdbc连接SQL Server数据库导出数据字典的功能时发现本地用jdk8和对应的SQL Server驱动(可通过SQLServer官网或者maven库下载-mssql-jdbc-8.2.2.jre8.jar)可以正常连接SQL Server2019,然后当我们导出jar包到项目中打算使用时,发现项目的环境是jdk1.6,这时程序与SQL Server2019无法正常建立连接,因为驱动是要在jre8的环境下才能运行的。这时我们就想换成jdk1.6支持的SQL Server驱动——sqljdbc4.jar,本以为换个驱动即可正常运行,结果发现接下来引发的异常竟让我折腾了一整天。

问题原因

jdk1.6因为安全套接字加密协议的不同,当连接SQL Server2014及以上版本时需要额外的jar包(bcpkix-jdk15on-1.60.jarbcprov-ext-jdk15on-1.60.jar)和修改java.security(jdk目录下的/jre/lib/security/java.security)使其能成功使用我们引入的包

解决过程

开始时,直接换了jar包后连接本地的SQL Server2019直接报异常:

  1. com.microsoft.sqlserver.jdbc.SQLServerException: 驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“java.lang.RuntimeException: Could not generate DH keypair”。
  2. at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1352)
  3. at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1533)
  4. at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1042)
  5. at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:817)
  6. at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:700)
  7. at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:842)
  8. at java.sql.DriverManager.getConnection(DriverManager.java:582)
  9. at java.sql.DriverManager.getConnection(DriverManager.java:185)
  10. Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
  11. at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
  12. at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1747)
  13. at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1708)
  14. at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1691)
  15. at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1222)
  16. at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1199)
  17. at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1483)

我在网上各种搜索发现大家都建议升级到jdk7+版本来解决,虽然这样一劳永逸,但是由于生产环境用的是1.6版本并不能轻易升级(很无奈,怪系统太旧了。。。),或者是使用低版本的SQL Server(2012版本或更低版本),但是博主希望的是在1.6版本下且所有SQL Server版本都能使用(还不是因为生产是1.6哇!orz)。由此开始了解决版本问题的漫漫长路。

  1. 下载上述列出的两个包后放入到jdk目录下jre\lib\ext

  2. 修改jre\lib\security\java.security:

找到“List of providers and their preference orders (see above):”下的security.provider信息,将
    security.provider.3=com.sun.net.ssl.internal.ssl.Provider
用#号进行注释并用以下代码进行替换(security.provider后有下划线的数字最好也按你们文件原有顺序排列下去)
    security.provider.3=net.tobszarny.ssl.java6.provider.BouncyCastleSSLProvider
    security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider

  1. #
  2. # List of providers and their preference orders (see above):
  3. #
  4. security.provider.1=sun.security.provider.Sun
  5. security.provider.2=sun.security.rsa.SunRsaSign
  6. #注释了下面这行,并重新添加
  7. #security.provider.3=com.sun.net.ssl.internal.ssl.Provider
  8. #试着奔跑的菜鸟添加的下面这行
  9. security.provider.3=net.tobszarny.ssl.java6.provider.BouncyCastleSSLProvider
  10. security.provider.4=com.sun.crypto.provider.SunJCE
  11. security.provider.5=sun.security.jgss.SunProvider
  12. security.provider.6=com.sun.security.sasl.Provider
  13. security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI
  14. security.provider.8=sun.security.smartcardio.SunPCSC
  15. security.provider.9=sun.security.mscapi.SunMSCAPI
  16. #试着奔跑的菜鸟添加的下面这行
  17. security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider

注意事项

在我搜索的方法中,有些人说是直接在原security.provider的末尾加上那两行代码即可,但是博主不行,一直报错(Unsupported curveId: 29)而必须将原有的ssl.Provider注释后替换那两行代码才能成功运行。博主猜测的是如果没有注释掉的话,安全套接字加密就用了原有的类而不是使用我们导入的jar包中的类了,但是暂不能保证是否会对其他安全套接字加密的功能有所影响。

最后再重新连接SQLServer即可,当然如果启动了服务器也要将服务器重启后再重试。

结语及反思

这次解决问题花费的时间很长,主要是一开始卡在找两个jar包的路上,因为在搜索引擎上搜到很多其他csdn的博客给出的jar都是需要积分下载的,很多下载后还货不对板 - _-|||,后来才发现Maven库这个东西,找对应版本的jar包简直不要太方便(在这里也不得不吐槽博主在csdn提供出去下载的东西还不能设置免积分)。
当然也希望以后做的都能用jdk8+,不然解决年代久远的环境问题可太累了。

才疏学浅,如文中有错误,感谢大家指出。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/692229
推荐阅读
相关标签
  

闽ICP备14008679号