j2ee|安全
安裝並配置SSL支援
什麼是Secure Socket Layer技術?
Secure Socket Layer(SSL)是一種允許Web瀏覽器和Web伺服器基於一種安全的串連方式串連起來的技術。在這種安全的串連中,要傳輸的資料在被傳輸前會被加密,然後在接到後立刻在處理資料前解密。瀏覽器和伺服器都會在發送任何資料前,加密所有的傳輸內容。SSL主要處理下面的重要安全事項。
l 認證
在你的初始嘗試與Web伺服器基於安全連線的通訊時,伺服器將給你的Web瀏覽器一個以伺服器憑證形式存在的認證集合。這個認證的目的就是驗證這個site是誰,並且他聲稱是什麼。在某些情況下,伺服器可能需要一個關於用戶端是誰,他聲稱是什麼的認證(這被稱作用戶端的認證)。
l 機密性
當資料在互連網上用戶端和伺服器間傳送時,第三方能夠看見並截獲資料。SSL的應答是被加密的,所以資料不會 被第三方解密,可以保持機密性。
l 完整性
當資料在互連網上用戶端和伺服器之間傳送時,第三方可以看見並截獲資料。SSL有助於保證資料不會再傳輸過程中被第三方修改。
要在你的獨立Web伺服器上安裝並配置SSL支援,你需要以下的構件。如果你正在使用J2EE1.4 應用伺服器,那麼SSL支援就已經被提供了。如果你正在使用一個別的Web伺服器,那麼參考你的產品文檔。
l 伺服器憑證密鑰商店(參考Setting Up Digital Certificates,page 933)。
l HTTPS連接器(參考配置SSL連接器,page 939)。
為了驗證SSL支援已經可用,參考驗證SSL Support(page 939)。
安裝數位憑證
注意:J2EE1.4應用伺服器的數位憑證已經被產生並且可以在目錄<J2EE_HOME>/domains/domain1/config中找到。
為了使用SSL,J2EE伺服器對於每個外在介面或者IP地址必須有個關聯的認證,這可以達到安全的串連。這種設計的原理是一個伺服器必須提供某種合理的關於此保證的擁有者是你認為的誰的保證,特別是在接收某些敏感的資訊之前。認為認證是一種對於網路地址的數位司機駕照的想法是有用的。它表明了這個site是與哪個公司聯絡起來的,同時說明了關於site所有者或者administrator的一些基本聯絡資訊。
數位憑證時被它的擁有者加密簽名的,並且很難被其他人偽造。對於包含在電子商務裡的網站,或者其他一些身份的認證十分重要的商業交易,認證可以從著名的認證授權機構(CA)比如Verisign或者Thawte購買。
如果認證不是真的重要,比如如果administrator只是簡單的想確認被伺服器傳輸和接收的資料是私人的,並且不能被監聽這次串連的某個人偷竊,你可以簡單的通過使用自己簽名的認證來節省購買CA認證的時間和花費。
SSL使用公開金鑰加密,這是基於金鑰組的。金鑰組包括一個公開金鑰和一個私密金鑰。如果資料用一個鑰匙加密,那麼它只能用另一個鑰匙解密。這一特性是在傳輸中建立信任和秘密的基礎。舉個例子,使用SSL,伺服器計算了一個值並使用私密金鑰加密這個值。加密過的值稱為數位簽章。用戶端使用伺服器的公開金鑰解密這個加密的值,並把這個值和自己的計算值比較。如果這兩個值匹配,用戶端就可以信任這個簽名是認證過的,因為只有私密金鑰可以用來產生這樣一個簽名。
數位憑證被用於在HTTPS協議中認證Web用戶端。大多數Web伺服器的HTTPS服務不會運行,除非數位憑證被安裝了。使用下面的大概的過程來建立能夠被你的Web伺服器用來啟用SSL的數位憑證。
一個可以被用來建立數位憑證的工具是keytool,它是個J2EE1.4應用伺服器內建的密鑰和認證管理工具。它使使用者可以管理他們自己的公開金鑰私密金鑰對和相關的認證,為了在self-authentication(使用者要向別的使用者或者服務認證自己)或者資料完整性和用數位簽章的認證服務時使用。它也允許使用者隱藏他們連絡人的公開金鑰(以認證的方式)。要更好的理解key-tool和公開金鑰加密,請閱讀keytool文檔,URL如下:
http://java.sun.com/j2se/1.4.2/docs/tooldocs/solaris/key-tool.html
建立伺服器憑證
伺服器的認證已經為J2EE1.4應用伺服器建立了。認證可以在<J2EE_HOME>/domains/domain1/config/目錄下找到。伺服器憑證在keystore.jks中。用戶端認證在cacerts.jks檔案中。
如果必要,你可以用keytool來產生認證。Keytool在一個與keystore對應的檔案中儲存了密鑰和認證。Keystore是一個儲存用於確認用戶端和伺服器的認證的倉庫。典型的,一個keystore包含一個用戶端或者一個伺服器的身份。預設的keystore把keystore當作一個檔案。它用一個密碼保護私密金鑰。
keystore是在你運行keytool的目錄下建立的。這個目錄可以是應用所在的目錄,也可以是許多應用共用的目錄。
為了建立一個伺服器憑證,
1.建立keystore。
2.從keystore中匯出認證。
3.簽署憑證。
4.把認證匯入一個trust-store中。Trust-store是指一個用於檢驗認證的認證倉庫。一個trust-store典型的包含多於一個認證。一個使用trust-store基於SSL的相互認證的例子將在Example:Client-Certificate Authentication over HTTP/SSL with JAX-RPC(page 950)中討論。
運行keytool來產生伺服器的keystore,我們把它取名為server-key-store.jks。這一步使用別名server-alias來產生一個新的公開金鑰和私密金鑰對,並把公開金鑰打包入server-keystore.jks的一個self-signed認證中。這個金鑰組是用RSA演算法和一個預設的changeit密碼產生的。要獲得更多關於keytool選項的資訊,請查閱它的線上協助,地址是
http://java.sun.com/j2ee/1.4.2/docs/tooldocs/solaris/keytool.html。
在你想建立keystore的目錄下帶著下面的參數運行keytool。當你按下Enter時,keytool提示你輸入伺服器名字,組織單位,組織,位置,國家,國家編碼。注意你必須輸入伺服器的名字在對keytool的第一個提示的應答中,它需要first和last name。抱著實驗的目的,可以是localhost。keystore中指定的主機必須與定義在主機變數<INSTALL>/j2eetutorial14/examples/common/buid.properties中的匹配。
1.產生伺服器憑證。
<JAVA_HOME>\bin\keytool -genkey -alias server-alias-keyalg RSA -keypass changeit -storepass changeit-keystore keystore.jks
2.把 keystore.jks中產生的認證匯出到檔案server.cer中。
<JAVA_HOME>\bin\keytool -export -alias server-alias
-storepass changeit -file server.cer -keystore keystore.jks
3.如果你想要擁有一個CA簽發的認證,請閱讀Signing Digital Certificates(page 937)獲得更多資訊。
4.要建立trust-store檔案cacerts.jks並把伺服器憑證添加到這個trust-store中,就要在你建立keystore和伺服器憑證的目錄下以如下的參數運行keytool。
<JAVA_HOME>\bin\keytool -import -v -trustcacerts
-alias server-alias -file server.cer
-keystore cacerts.jks -keypass changeit
-storepass changeit
認證的資訊,比如下面展示的將顯示出來。
<INSTALL>/j2eetutorial14/examples/gs 60% keytool -import
-v -trustcacerts -alias server-alias -file server.cer
-keystore cacerts.jks -keypass changeit -storepass changeit
Owner: CN=localhost, OU=Sun Micro, O=Docs, L=Santa Clara,
ST=CA, C=US
Issuer: CN=localhost, OU=Sun Micro, O=Docs, L=Santa Clara,
ST=CA, C=US
Serial number: 3e932169
Valid from: Tue Apr 08
Certificate fingerprints:
MD5: 52:9F:49:68:ED:78:6F:39:87:F3:98:B3:6A:6B:0F:90
SHA1: EE:2E:2A:A6:9E:03:9A:3A:1C:17:4A:28:5E:97:20:78:3F:
Trust this certificate? [no]:
5.輸入yes,然後敲擊Enter或者Return鍵。將出現如下的資訊。
Certificate was added to keystore
[Saving cacerts.jks]
簽發數位憑證
一旦你建立了數位憑證,你會想讓它被它的所有者簽名。一旦數位憑證被它的所有者加密簽名,他就很難被其他人偽造。對於電 子商務的網站或者其他身份認證很重要的商業事務中,認證可以向著名的認證授權機構(CA)比如Verisign或者Thawte購買。
如果認證不是很重要,比如如果administrator只是想簡單的確認被伺服器傳輸和接收的資料是私人的並且不會別其他監聽該串連的偷聽到,你可以簡單地通過使用self-signed認證來節省購買CA認證所需的時間和花費。
為了相互認證建立一個用戶端認證
這一節討論安裝一個用戶端的認證。當伺服器和用戶端的認證都可以用時,被稱為相互或者雙向的認證。在用戶端認證,用戶端需要提交由你選擇接受的CA發布的認證。在你想要建立用戶端認證的目錄下像下面給出的那樣運行keytool。當你按下Enter時,keytool提示你輸入伺服器名,組織單位,組織,地址,國家,國家代碼。注意你必須輸入伺服器的名字在對keytool的第一個提示的應答中,它需要first和last name。抱著實驗的目的,可以是localhost。keystore中指定的主機必須與定義在主機變數<INSTALL>/j2eetutorial14/examples/common/buid.properties中的匹配。
要建立一個名為client-keystore.jks的keystore,它包含名為client.cer的客戶認證,按照下面的步驟:
1.建立客戶認證。
<JAVA_HOME>\bin\keytool -genkey -alias client-alias -keyalg
RSA -keypass changeit -storepass changeit
-keystore keystore.jks
2.把產生的客戶認證匯出到client.cer檔案中。
<JAVA_HOME>\bin\keytool -export -alias client-alias
-storepass changeit -file client.cer -keystore keystore.jks
3.添加認證到trust-store檔案cacerts.jks中。在你建立keystore和客戶認證的目錄下以下面的參數運行keytool:
<JAVA_HOME>\bin\keytool -import -v -trustcacerts
-alias client-alias -file client.cer
-keystore cacerts.jks -keypass changeit
-storepass changeit
Keytool返回如下資訊:
Owner: CN=J2EE Client, OU=Java Web Services, O=Sun, L=Santa
Clara, ST=CA, C=US
Issuer: CN=J2EE Client, OU=Java Web Services, O=Sun, L=Santa
Clara, ST=CA, C=US
Serial number: 3e39e66a
Valid from: Thu Jan 30 18:58:50 PST 2003 until: Wed Apr 30
19:58:50 PDT 2003
Certificate fingerprints:
MD5: 5A:B0:4C:88:4E:F8:EF:E9:E5:8B:53:BD:D0:AA:8E:5A
SHA1:90:00:36:5B:E0:A7:A2:BD:67:DB:EA:37:B9:61:3E:26:B3:89:46:
32
Trust this certificate? [no]: yes
Certificate was added to keystore
一個使用相互認證的例子應用程式,參看Example: Client-Certificate Authentication over HTTP/SSL with JAX-RPC(page 950)。為了獲得關於驗證相互的認證在啟動並執行資訊,參看 Verifying Mutual Authentication is Running(page 941)。
多種關於認證的命令
l 要檢驗包含認證的keystore的內容,用別名server-alias:
keytool -list -keystore keystore.jks -alias server-alias -v
l 檢驗cacerts檔案的內容:
keytool -list -keystore cacerts.jks
配置SSL連接器
一個SSL連接器是預先為J2EE1.4 應用伺服器配置好的。你不需要配置任何東西。
驗證SSL支援
抱著測試,和驗證SSL支援已經被正確的安裝的目的,用一個連上在伺服器部署描述符中定義的連接埠的URL,載入預設的介紹頁面:
https://localhost:1043
在這個URL中的https表明瀏覽器應該正在使用SSL協議。在本例子中的localhost假設你正在你的本地機器上運行這個例子作為部署過程的部分內容。在例子中的1043是被指定的在配置SSL連接器(page 939)時SSL連接器建立的位置的安全連接埠。如果你正在使用一個不同的伺服器或者連接埠,相應的改變這個值。
使用者第一次載入這個應用時,New Site Certificate或者Security Alert dialog 會顯示出來。選擇Next來通過一系列的對話,當你到了最後的對話時選擇Finish。認證將只在第一次的時候顯示出來。當你接受這些認證時,網站以後的行為將會認為你信任這些內容。
運行SSL的一般提示
SSL協議被設計成儘可能有效率和安全。可是,加密/解密是一個從執行角度看很花費計算的過程。在SSL上運行一個完整的Web應用是不十分必須的,並且讓一個開發人員決定哪個頁面需要安全連線,哪個不需要,是符合慣例的。可能需要安全連線的頁麵包括登入頁面,個人資訊頁面,購物車的付款,或者信用卡資訊需要被傳輸的頁面。在一個應用中的任何頁面可以被簡單在地址前面加上https:替代http:來通過secure socket請求。任何絕對請求安全連線的頁面需要檢查與這一頁對應的協議的類型,並在如果https:沒有被指定時採取合適的動作。
在安全連線上使用基於名字的實際主機是被質疑的。這是SSL協議自身設計上的局限。用戶端瀏覽器接受伺服器憑證的SSL握手必須在HTTP請求被訪問之前發生。結果,包含實際主機名稱的請求資訊不能在認證前被判斷,並且這也是不可能對於一個IP地址簽發多個認證的原因。如果所有的基於一個IP地址的實際主機需要認證同一個認證,那麼多個主機的地址就應該在伺服器上不干擾普通的SSL操作。但是要知道,多數用戶端瀏覽器將比較伺服器的網域名稱和認證中列出的網域名稱,如果網域名稱不匹配,那麼瀏覽器將向客戶顯示警告。一般來說,在產品環境的SSL中普遍使用只有基於地址的主機。
開啟基於SSL的相互認證
這一節討論安裝用戶端的認證。當伺服器和用戶端的認證都可以用時,被稱為相互或者雙向的認證。在用戶端認證,用戶端需要提交由你選擇接受的CA發布的認證。至少有有兩種方法開啟用戶端認證。不管你選擇哪種,你都必須輸入keystore的位置和在Web伺服器設定檔中的密碼來開啟SSL,就像在Configuring the SSL Connector(page 939)中討論的那樣。這兩種開啟基於SSL的相互認證方法如下:
l 設定在認證域中clientAuth為true。按下面步驟來完成設定,
a.如果你還沒有啟動應用伺服器,就啟動它。啟動應用伺服器的資訊可以在Starting and Stopping the J2EE Application Server(page 91)中找到。
b.啟動Admin Console。啟動Admin Console的資訊可以在Starting the Admin Console(page 92)中找到。
c.在Admin Console樹中,展開Security,然後展開Realms,並選擇certificate。認證域被用於基於帶著SSL的HTTP的所有傳輸。
d.選擇Add來把clientAuth的屬性添加到伺服器上。在名字裡輸入clientAuth,在值裡輸入true。
e.點擊Save來儲存這些新的屬性。
f.登出Admin Console。
當你通過設定clientAuth屬性為true開啟用戶端的認證時,用戶端的認證將被所有的通過指定SSL連接埠的請求採用。
l 使用部署工具把認證的方法設定為Client-certificate。通過這種開啟用戶端認證的方式,用戶端的認證只是對被安全約束控制的指定資源有效。以這種方式設定用戶端認證將在Example:Client-Certificate Authentication over HTTP/SSL with JAX-RPC(page 950)中討論。
當用戶端認證以上述兩種方法開啟後,用戶端認證將被執行兩次。
檢驗相互的認證正在運行
你可以通過獲得debug資訊來檢驗相互的認證正在工作。這要在用戶端完成,並且這個例子展示了如何傳遞在targets.xml中的一個系統屬性來讓targets.xml產生一個在系統屬性中有javax.net.debug的客戶,這可以被添加到例如<INSTALL>/j2eetutorial14/examples/security/common/targets.xml檔案中。
為了使SSL相互認證的debug資訊可用,要傳遞系統屬性javax.net.debug=ssl,handshake,這可以提供關於相互認證是否啟動並執行資訊。下面的例子按照<INSTAL>/j2eetutorial14/examples/
security/common/targets.xml檔案定義了run-mutualauth-client任務,是通過像粗體示範的那樣添加sysproperty:
<target name="run-mutualauth-client"
description="Runs a client with mutual authentication over
SSL">
<java classname="${client.class}" fork="yes" >
<arg line="${key.store} ${key.store.password}
${trust.store} ${trust.store.password}
${endpoint.address}" />
<sysproperty key="javax.net.debug" value="ssl,
handshake" />
<sysproperty key="javax.net.ssl.keyStore"
value="${key.store}" />
<sysproperty key="java.net.ssl.keyStorePassword"
value="${key.store.password}"/>
<classpath refid="run.classpath" />
</java>
</target>