Soru Java 8'deki SQL Server JDBC Hatası: Sürücü, Güvenli Yuva Katmanı (SSL) şifrelemesi kullanarak SQL Server'a güvenli bir bağlantı kuramadı


Microsoft JDBC sürücüsü sürümünü kullanarak bir SQL Server veritabanına bağlanırken aşağıdaki hatayı alıyorum:

com.microsoft.sqlserver.jdbc.SQLServerException: Sürücü, Güvenli Yuva Katmanı (SSL) şifrelemesi kullanarak SQL Server'a güvenli bir bağlantı kuramadı. Hata: "SQL Server tamamlanmamış yanıt verdi. Bağlantı kapatıldı. ClientConnectionId: 98d0b6f4-f3ca-4683-939e-7c0a0fca5931".

Son zamanlarda Java 6 ve Java 7'den Java 8'e uygulamalarımızı geliştirdik. Java kullanan tüm sistemler SUSE Linux Enterprise Server 11'i (x86_64), VERSION = 11, PATCHLEVEL = 3'ü kullanıyor.

Burada yazdığım, 1000 veritabanı bağlantısını sırayla açan ve kapatan bir Java programı ile aldığım gerçekler.

  • Bağlantılar, bu hatanın yaklaşık% 5 -% 10'u ile düşürülür. Her bağlantıda hata oluşmaz.
  • SADECE sorun Java 8 ile ortaya çıkar. Java 7'de aynı programı çalıştırdım ve sorun tekrarlanabilir değil. Bu, geliştirmeden önceki üretim tecrübemizle tutarlıdır. Üretimde Java 7 altında sıfır sorun yaşıyorduk.
  • Sorun, Java 8'i çalıştıran tüm Linux sunucularımızda OLMAZ, sadece bazılarında gerçekleşir. Bu benim için şaşırtıcı, ama aynı Linux Linux Linux sürümüyle aynı test programını çalıştırdığımda (1.8.0_60, 64 bit), Linux örneklerinden birinde sorun oluşmaz, fakat sorun başkalarında meydana gelir. Linux örnekleri aynı SUSE sürümünü kullanıyor ve aynı yama seviyesinde.
  • Sorun, BOTH SQL Server 2008 ve SQL Server 2014 sunucularına / veritabanlarına bağlanırken oluşur.
  • SQL Server JDBC sürücüsünün 4.0 sürümünü veya sürücünün daha yeni 4.1 sürümünü kullanmam durumunda sorun oluşur.

Gözlemlerimi web'deki diğer kullanıcılarla karşılaştırıldığında benzersiz kılan şey, SADECE, Java 8'de sorun olmasına rağmen, aynı Java 8 JVM'yi çalıştıran, görünüşte özdeş Linux sunucularında bir sorun ortaya çıkarılamam. Diğer insanlar bu problemi Java'nın daha önceki sürümlerinde de görmüşlerdir, fakat bu bizim deneyimimiz değildi.

Sahip olabileceğiniz herhangi bir girdi, öneri veya gözlem takdir edilir.


18
2017-09-24 16:09


Menşei




Cevaplar:


Sorunu yeniden üreten bir Linux örneğindeki Java 8 JVM'de SSL günlük kaydını açtım. SSL günlüğü kullanılarak açık -Djavax.net.debug=ssl:handshake:verbose. Bu bazı yararlı bilgiler ortaya koydu.

geçici çözüm Üretimde kullandığımız ve bizim için çalıştığı kanıtlanmış olan bu parametrenin JVM'de ayarlanmasıdır:

 -Djdk.tls.client.protocols=TLSv1

Daha fazla ayrıntı istiyorsanız, lütfen okuyun.

Sorunun tekrarlanabileceği bir sunucuda (yine, yalnızca% 5-10), şunları gözlemledim:

*** 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

Dikkat edin TLSv1.2 veritabanı sunucusu tarafından seçilir ve bu değişimde kullanılır. Bağlantılar sorunlu linux hizmetinden başarısız olduğunda, TLSv1.2'nin seçili olan seviyenin DAİMA olduğunu gözlemledim. Ancak, TLSv1.2 kullanıldığında bağlantılar DAİMA başarısız olmaz. Sadece% 5-10 oranında başarısız oluyorlar.

Şimdi burada sorun olan bir sunucudan bir değişim. Diğer her şey eşittir. I.e., aynı veri tabanına, JVM'nin aynı versiyonuna (Java 1.8.0_60), aynı JDBC sürücüsüne, vb. Bağlandığına dikkat edin. TLSv1 hatalı sunucu durumunda olduğu gibi TLSv1.2 yerine veritabanı sunucusu tarafından seçilir.

*** 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

Bu yüzden, TLSv1, Linux JVM ve SQL Server arasında müzakere edildiğinde, bağlantılar DAİMA başarılı olur. TLSv1.2 müzakere edildiğinde, sporadik bağlantı hataları alıyoruz.

(Not: Java 7 (1.7.0_51) her zaman TLSv1 üzerinde anlaşır, bu nedenle sorun bizim için hiçbir zaman Java 7 JVM ile gerçekleşmemiştir.)

Hala sahip olduğumuz açık sorular:

  1. NEDEN, 2 farklı Linux sunucusundan aynı Java 8 JVM çalıştırması, her zaman TLSv1 üzerinde anlaşma yapacaktır, ancak başka bir Linux sunucusundan bağlanırken, her zaman TLSv1.2 üzerinde anlaşır.
  2. Ayrıca, TLSv1.2 anlaşmalı bağlantıların neden bu sunucudaki zamanın çoğunun başarılı olmasa da başarılı olmasın?

Güncelleme 6/10/2017: Bu Microsoft'tan gönderiyor Sorunu ve çözüm önerilerini açıklar.

Kaynaklar:

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- soketler-tabakalı-SSL-encryption.aspx

Java 8, JCE Sınırsız Gücü Politikası ve TLS üzerinden SSL Handshake

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


17
2017-09-24 16:09



Sürücünün yeni sürümünü denediniz mi? - Mark Rotteveel
Selam Mark. Hayır, artık bu organizasyonda çalışmadığım için daha yeni bir versiyon denemedim. - 2Aguy


Bu MS SQL JDBC sürücüsünün 4.2 sürümünde düzeltilmiş gibi görünüyor. Sunucuya 1000 kez bağlandığım ve her denemede 100ms durakladığım bir program oluşturdum. Sürüm 4.1 ile, her seferinde problemi yeniden üretebildim, ancak sadece sporadik bir şekilde gerçekleşti. 4.2 sürümü ile sorunu yeniden oluşturamadım.


4
2017-09-28 15:12



Bu iyi bir bilgi. Ancak, sürüm 4.2 sürücüsü Java 7 altında çalışmaz (en az bir ay önce kontrol ettim). Microsoft, Java 6, 7 ve 8 ile uyumlu olduğunu iddia ediyor, ancak görünüşe göre bir Java 8 derleyicisi ile sürücü kodunu derlediler. Java 7 ve Java 8'i çalıştıran karma ortamımızda, bu sorun nedeniyle 4.2 sürücüsünü çalıştıramıyoruz. Görmek social.msdn.microsoft.com/Forums/en-US/... - 2Aguy


SQL JDBC Sürücüsünü yükseltmeden önce, önce uyumluluğu kontrol edin:

  • Sqljdbc.jar 5 JRE gerektirir ve JDBC 3.0 API'sini destekler
  • Sqljdbc4.jar, 6 JRE gerektirir ve JDBC 4.0 API'sini destekler.
  • Sqljdbc41.jar, 7 JRE gerektirir ve JDBC 4.1 API'sini destekler
  • Sqljdbc42.jar, JRE of 8 gerektirir ve JDBC 4.2 API'sini destekler

Kaynak: https://www.microsoft.com/en-us/download/details.aspx?id=11774


3
2017-10-14 14:00





Ayrıca Windows Server 2012 R2'de JDBC sürücüsü 4.0 ve 4.1'yi Java 7 ile kullanarak bu soruna da girdim. Microsoft makalesi DHE ciphersuites üzerindeki suçu işaretler ve JDBC sürücüsü 4.2'ye yükseltemezseniz bunları devre dışı bırakmanızı veya önceliklerini azaltmanızı önerir


1
2018-06-09 02:11



Bu soruya bir cevap vermemektedir. Yeterli olduğunda itibar yapabileceksin yorum Yap herhangi bir gönderide. Bunu da kontrol et bunun yerine ne yapabilirim. - thewaywewere


Microsoft Geçenlerde kendi sürücülerini açık kaynaklı. Biri görebiliyor mssql-jdbc GitHub'da sürücü etkinliği. Sanırım en son önizleme versiyonu 6.1.5.

Ayrıca tüm önizleme versiyonlarını maven'de de bulabilirsiniz. JDK7 ve JDK 8'in her ikisini de destekler.


0
2018-04-05 20:07