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通信日誌的代碼如下:
- System.setProperty("javax.net.debug", "ssl,handshake");
- *** ClientHello, TLSv1
- ...
- main, WRITE: TLSv1 Handshake, length = 75
- main, WRITE: SSLv2 client hello message, length = 101
- main, READ: TLSv1 Handshake, length = 81
- *** ServerHello, TLSv1
- ...
- main, READ: TLSv1 Handshake, length = 3747
- ...
- main, WRITE: TLSv1 Change Cipher Spec, length = 1
- ...
- main, WRITE: TLSv1 Handshake, length = 48
- main, READ: TLSv1 Change Cipher Spec, length = 1
- main, READ: TLSv1 Handshake, length = 48
- ...
- main, WRITE: TLSv1 Application Data, length = 336
- main, READ: TLSv1 Application Data, length = 336
如何設置SSL客戶端採用哪種協議?
1、在Java中,如果採用 SSLSocket 或 SSLEngine 實現SSL客戶端,可以通過 setEnabledProtocols(String[] protocols) 方法設置SSL客戶端能夠使用的協議。示例代碼片斷如下:
- SocketFactory sf = SSLSocketFactory.getDefault();
- SSLSocket socket = (SSLSocket) sf.createSocket("localhost", 8443);
- // 設置SSL客戶端使用的協議
- String[] protocols = { "TLSv1" };
- socket.setEnabledProtocols(protocols);
2、在Java中,如果採用 HttpsURLConnection 實現SSL客戶端,可以在 HttpsURLConnection 的相關代碼之前通過系統屬性“https.protocols”來指定SSL客戶端使用的協議。代碼如下:
- 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服務端所支持的協議。示例代碼如下:
- <Connector
- port="8443"
- protocol="HTTP/1.1"
- SSLEnabled="true"
- maxThreads="150"
- scheme="https"
- secure="true"
- clientAuth="false"
- sslProtocol="TLS" />
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,示例代碼如下:
- <Connector
- port="8443"
- protocol="HTTP/1.1"
- SSLEnabled="true"
- maxThreads="150"
- scheme="https"
- secure="true"
- clientAuth="false"
- sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2" />
如果讀者採用其他Web服務器對外提供https服務,例如:Apache、WebLogic、WebSphere等,也都有類似的屬性設置服務端所支持的SSL協議,筆者就不在此贅述了。相信讀完本篇文章,開發人員應該能夠輕鬆應對SSL 3.0 Poodle漏洞,同時,也應該清楚公衆平臺調整SSL安全策略後如何修改自己的程序代碼。