SSL 3.0曝出Poodle漏洞的解決方案-----開發者篇

SSL 3.0曝出高危漏洞

2014年10月15日,Google研究人員公佈SSL 3.0協議存在一個非常嚴重的漏洞,該漏洞可被黑客用於截取瀏覽器與服務器之間進行傳輸的加密數據,如網銀賬號、郵箱賬號、個人隱私等等。SSL 3.0的漏洞允許攻擊者發起降級攻擊,即欺騙瀏覽器說“服務器不支持更安全的安全傳輸層(TLS)協議”,然後強制其轉向使用SSL 3.0,在強制瀏覽器採用SSL 3.0與服務器進行通訊之後,黑客就可以利用中間人攻擊來解密HTTPs的cookies,Google將其稱之爲POODLE攻擊,若受到POODLE攻擊,所有在網絡上傳輸的數據將不再加密。

筆者也是在微信公衆平臺發出“公衆平臺調整SSL安全策略,請開發者注意升級”的通知時,纔開始關注SSL3.0漏洞,纔開始意識到問題的嚴重性。通知的主要內容:“近一段時間HTTPS加密協議SSL曝出高危漏洞,可能導致網絡中傳輸的數據被黑客監聽,對用戶信息、網絡賬號密碼等安全構成威脅。爲保證用戶信息以及通信安全,微信公衆平臺將關閉掉SSLv2、SSLv3版本支持,不再支持部分使用SSLv2、 SSLv3或更低版本的客戶端調用。請仍在使用這些版本的開發者於11月30日前儘快修復升級。


知識普及1:SSL協議要點

SSL(Secure Sockets Layer 安全套接層)是一種基於Web應用的安全通信協議,最早由Netscape(網景)公司提出。SSL介於TCP協議和應用層協議之間,主要作用就是將HTTP、FTP等應用層的數據進行加密然後依託可靠的TCP協議在互聯網上傳輸到目的地,其中最典型的應用就是https。

SSL提供3個基本的安全服務

1)身份合法性:數據發送方和接收方要確認彼此身份,要確保各自的身份不會被冒充。

2)數據機密性:所有傳輸的數據都進行加密,並且要確保即使數據被截獲也無法破解。

3)數據完整性:確保收到的數據與發送方發出的數據一致,沒有被篡改。

SSL協議主要採用的數據加密算法

1)非對稱加密算法:數據加密和解密使用不同的密鑰,如RSA公鑰加密算法。優點是安全級別高,很難被破解;缺點是加密解密的速度慢,因此只適用於小量數據的加密。SSL協議採用非對稱加密算法實現數字簽名,驗證數據發送方(或接收方)的身份,同時也用非對稱加密算法交換密鑰(用於數據加密的對稱加密算法的密鑰,以及用於數據完整性驗證的MAC算法)。

2)對稱加密算法:數據加密和解密使用同一個密鑰,如DES、3DES、RC4等都是對稱加密算法。優點是加解密速度快,適用於大數據量的加密,但安全性較差。SSL協議採用對稱加密算法對傳輸的數據進行加密。

3)MAC算法:Message Authentication Codes,即消息認證碼算法,MAC含有密鑰散列函數算法,兼容了MD和SHA算法的特性,並在此基礎上加入了密鑰。SSL協議採用MAC算法來檢驗消息的完整性。


知識普及2:SSL協議的版本

目前在用的SSL協議主要有5個版本,分別是SSL2.0、SSL3.0、TLS1.0、TLS1.1和TLS1.2,這裏的TLS(Transport Layer Security,傳輸層安全)協議是SSL協議的升級版。
在SSL協議曝出Poodle漏洞後,微信公衆平臺將取消對SSLv2、SSLv3兩個版本的支持,瀏覽器及其他採用SSL協議的平臺也會逐漸取消對SSLv2、SSLv3的支持,目前只建議使用TLSv1.0、TLSv1.1和TLSv1.2三個版本。


如何查看所採用的SSL協議?

在Java開發中,在SSL服務端或客戶端代碼之前設置系統屬性“javax.net.debug”爲“ssl,handshake”就能夠將SSL通信日誌輸出到控制檯。開啓SSL通信日誌的代碼如下:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. System.setProperty("javax.net.debug""ssl,handshake");  
下面是筆者測試調用微信公衆平臺接口獲取access_token所產生的SSL通信日誌的一部分。從日誌中可以看到,這次通信過程一共用到了SSLv2和TLSv1兩種協議。其中,SSLv2協議用於客戶端向服務器發送hello消息,而TLSv1協議用於握手、交換密鑰和數據加密。

[plain] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. *** ClientHello, TLSv1  
  2. ...  
  3. main, WRITE: TLSv1 Handshake, length = 75  
  4. main, WRITE: SSLv2 client hello message, length = 101  
  5. main, READ: TLSv1 Handshake, length = 81  
  6. *** ServerHello, TLSv1  
  7. ...  
  8. main, READ: TLSv1 Handshake, length = 3747  
  9. ...  
  10. main, WRITE: TLSv1 Change Cipher Spec, length = 1  
  11. ...  
  12. main, WRITE: TLSv1 Handshake, length = 48  
  13. main, READ: TLSv1 Change Cipher Spec, length = 1  
  14. main, READ: TLSv1 Handshake, length = 48  
  15. ...  
  16. main, WRITE: TLSv1 Application Data, length = 336  
  17. main, READ: TLSv1 Application Data, length = 336  


如何設置SSL客戶端採用哪種協議?

1、在Java中,如果採用 SSLSocket 或 SSLEngine 實現SSL客戶端,可以通過 setEnabledProtocols(String[] protocols) 方法設置SSL客戶端能夠使用的協議。示例代碼片斷如下:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. SocketFactory sf = SSLSocketFactory.getDefault();  
  2. SSLSocket socket = (SSLSocket) sf.createSocket("localhost"8443);  
  3. // 設置SSL客戶端使用的協議  
  4. String[] protocols = { "TLSv1" };  
  5. socket.setEnabledProtocols(protocols);  

2、在Java中,如果採用 HttpsURLConnection 實現SSL客戶端,可以在 HttpsURLConnection 的相關代碼之前通過系統屬性“https.protocols來指定SSL客戶端使用的協議。代碼如下:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. System.setProperty("https.protocols""TLSv1");  

如何設置SSL服務端支持哪些協議?

1、在Java中,如果採用 SSLSocket 或 SSLEngine 實現SSL服務端,同樣也是使用 setEnabledProtocols(String[] protocols) 方法設置SSL服務端支持的協議。

2、在Java中,如果是通過Tomcat對外提供https服務,可以通過設置%tomcat%/conf/server.xml中的sslProtocol屬性指定SSL服務端所支持的協議。示例代碼如下:

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <Connector   
  2.     port="8443"   
  3.     protocol="HTTP/1.1"   
  4.     SSLEnabled="true"  
  5.     maxThreads="150"   
  6.     scheme="https"   
  7.     secure="true"  
  8.     clientAuth="false"  
  9.     sslProtocol="TLS" />  
sslProtocol屬性的設置說明:

1)如果設置setProtocol="TLSv1",那麼服務端將支持SSLv3和TLSv1;

2)如果設置setProtocol="TLSv1.1",那麼服務端將支持SSLv3、TLSv1和TLSv1.1;

3)如果設置setProtocol="TLSv1.2",那麼服務端將支持SSLv3、TLSv1、TLSv1.1和TLSv1.2。

如果服務端不支持SSLv3,只支持TLSv1、TLSv1.1和TLSv1.2,又該如何設置呢?這時需要設置另外一個屬性sslEnabledProtocols,示例代碼如下:

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <Connector   
  2.     port="8443"   
  3.     protocol="HTTP/1.1"   
  4.     SSLEnabled="true"  
  5.     maxThreads="150"   
  6.     scheme="https"   
  7.     secure="true"  
  8.     clientAuth="false"  
  9.     sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2" />  

如果讀者採用其他Web服務器對外提供https服務,例如:Apache、WebLogic、WebSphere等,也都有類似的屬性設置服務端所支持的SSL協議,筆者就不在此贅述了。相信讀完本篇文章,開發人員應該能夠輕鬆應對SSL 3.0 Poodle漏洞,同時,也應該清楚公衆平臺調整SSL安全策略後如何修改自己的程序代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章