在測試服務器上,java程序啓動的時候,日誌裏面出現javax.net.ssl.SSLHandshakeException,這個錯誤目前尚未發現是什麼緣由致使的,大機率是有人升級了mysql或者jdk的版本。 在查找多方資料發現,是jdk8和mysql支持的協議不一致致使的。
mysql版本:5.7.34
jdk版本:1.8.0_292html
1.jdk8從小版本JDK8u261開始支持TLS1.3,默認TLS1.2以前的協議在security裏面是禁用的,因此從JDK8u261開始只有TLS1.2和1.3是默認啓用的。jdk jsse連接java
The JSSE API supports the following security protocols:
TLS: version 1.0, 1.1, 1.2, and 1.3 (since JDK 8u261)
SSL (Secure Socket Layer): version 3.0
複製代碼
2.mysql對於ssl的支持,咱們看下網上的描述:mysql
TLS versions: The allowable versions of TLS protocol can be restricted using the connection properties enabledTLSProtocols and, for X DevAPI connections and for release 8.0.19 and later, xdevapi.tls-versions (when xdevapi.tls-versions is not specified, it takes up the value of enabledTLSProtocols). If no such restrictions have been specified, Connector/J attempts to connect to the server with the following TLS versions:
TLSv1,TLSv1.1,TLSv1.2,TLSv1.3 for MySQL Community Servers 8.0, 5.7.28 and later, and 5.6.46 and later, and for all commercial versions of MySQL Servers.
TLSv1,TLSv1.1 for all other versions of MySQL Servers.
Notes
For Connector/J 8.0.26 and later: The TLSv1 and TLSv1.1 protocols have been deprecated. While connections to the server using those TLS versions can still be made with the same negotiation process as described above, for any connections established using those TLS versions, Connector/J writes to its logger the message "This connection is using TLSv1[.1] which is now deprecated and will be removed in a future release of Connector/J."
For Connector/J 8.0.18 and earlier when connecting to MySQL Community Server 5.6 and 5.7 using the JDBC API: Due to compatibility issues with MySQL Server compiled with yaSSL, Connector/J does not enable connections with TLSv1.2 and higher by default. When connecting to servers that restrict connections to use those higher TLS versions, enable them explicitly by setting the Connector/J connection property enabledTLSProtocols (e.g., set enabledTLSProtocols=TLSv1,TLSv1.1,TLSv1.2).
複製代碼
這裏很清楚的說明了,若是沒有指定協議的狀況下,在8.0.26以及以後的版本,TLS1.0和TLS1.1已經被廢棄,可是能夠做爲握手的協議,會在mysql的日誌記錄器中提示這些協議會在將來被刪除。 對於8.0.18以及以前的版本,包括5.6,5.7來講,爲了兼容性的緣由,不會啓用1.2以及更高版本的TLS協議,因此mysql5.7這裏默認是TLS1.0,TLS1.1被使用。 而jdk這邊默認使用TLS1.2,TLS1.3。因此協議徹底對不上,就在握手的時候報了SSLHandshakeException。spring
如下有三種解決方式:
第一種暴力的把jdk默認禁用安全協議給去掉了(或者只去掉TLS1.0和TLS1.1也能夠),不太推薦使用,JDK默認的協議你給它直接暴力註釋,總歸是會帶來一些安全問題。
第二種方式也很蠻力直接把ssl給去掉了,雙方直接不使用ssl,也不太推薦使用,理由同上
第三種方式直接指定使用某種雙方都支持的協議,mysql說了爲了兼容問題不主動使用TLS1.2協議,這裏確認沒有兼容性問題,直接指定協議便可。sql
在服務器輸入命令:
which is java
返回:
/usr/bin/java
輸入:ls -l /usr/bin/java
返回:/usr/bin/java -> /etc/alternatives/java
輸入:ls -l /etc/alternatives/java
返回:/etc/alternatives/java -> /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
而後知道java的目錄以後,一步步進入到/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security
cd /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security
編輯java.sercurity
sudo vim java.security
而後搜索 SSLv3,找到 jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, 相似的行
而後把這幾行給註釋掉
# Example:
# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
# 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
保存退出,而後重啓java服務
複製代碼
在鏈接數據庫的地方設置不使用ssl,參數加上useSSL=false數據庫
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/database?useSSL=false
複製代碼
在鏈接後指定協議TLSv1.2vim
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/database?enabledTLSProtocols=TLSv1.2
複製代碼
1.stackoverflow問題
2.mysql鏈接ssl
3.JSSEapi