Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Lỗi JDBC của SQL Server trên Java 8:Trình điều khiển không thể thiết lập kết nối an toàn với SQL Server bằng cách sử dụng mã hóa Lớp cổng bảo mật (SSL)

Tôi đã bật tính năng đăng nhập SSL trong Java 8 JVM trên phiên bản Linux tái tạo sự cố. Ghi nhật ký SSL được bật bằng cách sử dụng -Djavax.net.debug=ssl:handshake:verbose . Điều này tiết lộ một số thông tin hữu ích.

Giải pháp thay thế mà chúng tôi đang sử dụng trong sản xuất và đã được chứng minh là hiệu quả với chúng tôi là đặt thông số này trên JVM:

 -Djdk.tls.client.protocols=TLSv1

Nếu bạn muốn biết thêm chi tiết, vui lòng đọc tiếp.

Trên máy chủ mà sự cố có thể được tái tạo (một lần nữa, chỉ 5-10% thời gian), tôi đã quan sát thấy những điều sau:

*** ClientHello, TLSv1.2
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Handshake, length = 195
main, READ: TLSv1.2 Handshake, length = 1130
*** ServerHello, TLSv1.2
--- 8<-- SNIP -----
%% Initialized:  [Session-79, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256]
** TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
--- 8<-- SNIP -----
Algorithm: [SHA1withRSA]
--- 8<-- SNIP -----
*** Diffie-Hellman ServerKeyExchange
--- 8<-- SNIP -----
*** ServerHelloDone
*** ClientKeyExchange, DH
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Handshake, length = 133
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Change Cipher Spec, length = 1
*** Finished
verify_data:  { 108, 116, 29, 115, 13, 26, 154, 198, 17, 125, 114, 166 }
***
main, WRITE: TLSv1.2 Handshake, length = 40
main, called close()
main, called closeInternal(true)
main, SEND TLSv1.2 ALERT:  warning, description = close_notify
main, WRITE: TLSv1.2 Alert, length = 26
main, called closeSocket(true)
main, waiting for close_notify or alert: state 5
main, received EOFException: ignored
main, called closeInternal(false)
main, close invoked again; state = 5
main, handling exception: java.io.IOException: SQL Server returned an incomplete response. The connection has been closed. ClientConnectionId:12a722b3-d61d-4ce4-8319-af049a0a4415

Lưu ý rằng TLSv1.2 được chọn bởi máy chủ cơ sở dữ liệu và được sử dụng trong trao đổi này. Tôi đã quan sát thấy rằng, khi các kết nối không thành công từ dịch vụ linux có vấn đề, TLSv1.2 LUÔN LUÔN là mức được chọn. Tuy nhiên, kết nối không LUÔN LUÔN bị lỗi khi TLSv1.2 được sử dụng. Họ chỉ thất bại 5-10% thời gian.

Bây giờ đây là một cuộc trao đổi từ một máy chủ KHÔNG có vấn đề. Mọi thứ khác đều bình đẳng. Tức là, kết nối với cùng một cơ sở dữ liệu, cùng một phiên bản JVM (Java 1.8.0_60), cùng một trình điều khiển JDBC, v.v. Lưu ý rằng, tại đây, TLSv1 được máy chủ cơ sở dữ liệu chọn thay vì TLSv1.2 như trong trường hợp máy chủ bị lỗi.

*** ClientHello, TLSv1.2
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Handshake, length = 207
main, READ: TLSv1 Handshake, length = 604
*** ServerHello, TLSv1
--- 8<-- SNIP -----
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA
--- 8<-- SNIP -----
%% Initialized:  [Session-79, TLS_RSA_WITH_AES_128_CBC_SHA]
** TLS_RSA_WITH_AES_128_CBC_SHA
--- 8<-- SNIP -----
Algorithm: [SHA1withRSA]
--- 8<-- SNIP -----
***
*** ServerHelloDone
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1
--- 8<-- SNIP -----
main, WRITE: TLSv1 Handshake, length = 134
main, WRITE: TLSv1 Change Cipher Spec, length = 1
*** Finished
verify_data:  { 26, 155, 166, 89, 229, 193, 126, 39, 103, 206, 126, 21 }
***
main, WRITE: TLSv1 Handshake, length = 48
main, READ: TLSv1 Change Cipher Spec, length = 1
main, READ: TLSv1 Handshake, length = 48
*** Finished

Vì vậy, khi TLSv1 được thương lượng giữa Linux JVM và SQL Server, các kết nối LUÔN LUÔN thành công. Khi TLSv1.2 được thương lượng, chúng tôi nhận được các lỗi kết nối lẻ tẻ.

(Lưu ý:Java 7 (1.7.0_51) luôn thương lượng TLSv1, đó là lý do tại sao sự cố không bao giờ xảy ra với chúng tôi với Java 7 JVM.)

Các câu hỏi mở mà chúng tôi vẫn có là:

  1. TẠI SAO cùng một JVM Java 8 chạy từ 2 máy chủ Linux khác nhau sẽ luôn thương lượng TLSv1, nhưng khi kết nối từ một máy chủ Linux khác, nó luôn thương lượng TLSv1.2.
  2. Và cũng là lý do tại sao các kết nối được thương lượng TLSv1.2 thành công hầu hết, nhưng không phải tất cả, mọi lúc trên máy chủ đó?

Cập nhật ngày 6 tháng 10 năm 2017: Bài đăng này từ Microsoft mô tả sự cố và giải pháp được đề xuất của họ.

Tài nguyên:

http://www.infoworld.com/article/2849292/operating-systems/more-patch-problems-reported-with-the-ms14-066-kb-2992611-winshock-mess.html

http://www.infoworld.com/article/2849292/operating-systems/more-patch-problems-reported-with-the-ms14-066-kb-2992611-winshock-mess.html

http://blogs.msdn.com/b/jdbcteam/archive/2008/09/09/the-driver-could-not-establish-a-secure-connection-to-sql-server-by-using-secure- sockets-layer-ssl-crypt.aspx

Java 8, Chính sách sức mạnh không giới hạn của JCE và Bắt tay SSL qua TLS

http://blogs.msdn.com/b/saponsqlserver/archive/2013/05/10/analyzing-jdbc-connection-issues.aspx

https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#descPhase2

https://blogs.oracle.com/java-platform-group/entry/java_8_will_use_tls



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mẹo sử dụng SQL Server với Salesforce

  2. Kích hoạt đăng nhập trong SQL Server

  3. Các ký tự thoát khỏi tìm kiếm toàn văn bản trong SQL Server?

  4. Làm cách nào để đặt chuỗi kết nối SQL Server?

  5. Tìm hiểu Luôn luôn BẬT Nhóm sẵn có giữa các Phiên bản Máy chủ SQL dựa trên Linux. Phần 1