2011-06-07 34 views
3

我試圖從Web服務請求客戶端提交客戶端證書的數據。服務器使用SSL進行所有通信,並使用自簽名證書。我向Netbeans提供了該服務的WSDL文件,並生成了帶有wsimport的客戶端代碼。將Glassfish配置爲使用雙向SSL的Web服務的客戶端

當我的客戶端代碼寫入常規Java應用程序時,我沒有任何問題;我將信任庫設置爲包含服務器證書的cacerts文件,將密鑰庫設置爲服務器管理員以JKS格式提供的包含2個密鑰的文件 - 客戶機私鑰和服務器的公鑰,構建請求對象,以及發送請求。

將問題轉移到企業Java環境時出現問題。要求規定代碼必須是在Glassfish應用程序服務器上運行的Enterprise Archive內的Enterprise JavaBean。看起來Glassfish有自己的安全設置來覆蓋JVM的設置。當包含Web服務調用的EJB方法運行時,SSL協商失敗:javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target。我不知道如何像我的JVM的設置一樣設置Glassfish的安全設置,任何人都可以解釋Glassfish的安全設置嗎?我所做的研究僅顯示瞭如何將Glassfish設置爲Web服務服務器,而不是Web服務客戶端

我有一個服務器的.cer證書文件,我通過使用Java的keytool將其添加到默認的cacerts文件中,將它添加到我的信任存儲中。 如果將cacerts文件修改爲InstallCert以包含自簽名證書,請按照http://blog.johnryding.com/post/1548502059/acquire-an-ssl-certificate-for-your-java-programs-in-win的步驟更好地修改?

我有存儲在$ JAVA_HOME/jre/lib/security和$ JAVA_HOME/lib/security中的信任存儲文件,密鑰存儲文件以及.cer證書文件和.p12瀏覽器證書。

我使用Netbeans 6.9.1和Glassfish 3.1 Final。相關的一段代碼如下,從我的EJB中複製而來。最後一行發生異常。

System.setProperty("javax.net.ssl.trustStore", "C:\\jssecacerts"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); System.setProperty("javax.net.ssl.keyStore", "C:\\userCertificate.jks"); System.setProperty("javax.net.ssl.keyStorePassword", "password");
RequestObject request = new RequestObject;
request.setQuery("some data");
request.setUsername("user");
request.setPassword("pass");
Service service = new Service();
Endpoint port = service.getWebServicePort();
Result result = port.specificWebServiceMethod(request);

+0

你解決了這個問題嗎?我面對同樣的情況。如果你有東西,請提供詳細信息。 – mahesh 2011-11-18 11:43:12

回答

1

而不是使用全局系統屬性的,你應該爲你的客戶端的獨立SSLContext。那麼它是否在Glassfish服務器中運行並不重要。

下面是應該是相關的(有關客戶證書WS)一個問題:Choosing SSL client certificate in Java

1

我有這個確切的問題(與Glassfish的3.0.1)。

下面是我們解決這個問題的確切步驟。

    • 一個。使用java keytool命令查看密鑰庫以查看密鑰庫中的內容。這有助於稍後查看是否有任何更改。命令有點像

      keytool -list -keystore MyKeyStore.jks 
      
    • b。使用openssl將pfx轉換爲pem。請注意,我爲輸入pfx使用了正確的密碼,並且對於pem文件輸出使用了與我的java密鑰庫相同的密碼。

      openssl pkcs12 -in MyPfxFile.pfx -out MyPemFile.pem 
      
  1. PEM文件轉換爲可以容易地導入到Java密鑰爲P12。請注意,我在我的java密鑰庫中使用了與輸入和輸出文件相同的密碼。

    openssl pkcs12 -export -in MyPemFile.pem -out MyP12File.p12 
    
  2. 現在我最後將p12導入到我的java密鑰庫中。請注意,我使用java 6,java 5 keytool不支持-importkeystore參數。

    keytool -importkeystore -deststorepass MyPassword -destkeystore PathToMyKeystore/keystore.jks -srckeystore MyP12File.p12 -srcstoretype PKCS12 -srcstorepass MyPassword 
    
  3. 你可以在這裏列出密鑰庫的內容,像這樣的keytool -list -keystore keystore.jks只是爲了確保你的新的關鍵是正確導入。

如果你像我一樣幸運,你會發現在這一點上啓動你的應用服務器將是沒有用的。你會看到有關pkix路徑或HTTP 403 Forbidden的一些錯誤。

以上使用的步驟完美適用於Sun Application Server 9.1_1,但不適用於Oracle Glassfish 3.0.1。我認爲這與第3部分中使用的JSSE版本相比,與Sun App Server或jdk版本相關。如果僅將客戶端證書添加到密鑰存儲庫,那麼將以下jvm選項添加到您的ogs 3 domain.xml文件應該可以解決問題。

<jvm-options>-Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol</jvm-options> 

我也注意到,有人說不要使用JVM選項上述聲明,但它是固定的一部分,不使用它,看看它是否工作,我敢打賭,它不會。也許只是改變處理程序就是爲什麼它可以工作?

這裏就是我發現的所有細節:http://onjava.com/pub/a/onjava/2001/05/03/java_security.html?page=4

我還隔着一個最終的問題(僅適用於OGS 3)迷迷糊糊的,如果你失敗,現在每一次我建議尋找InstallCert應用程序(它在那裏)併爲其提供以下命令行參數: 每次嘗試調用Web服務時,都會收到這些PKIX錯誤。

希望這可以幫助別人。這些類型的問題,真讓我想撕毀我的頭髮:)

4

我面對的是,上述雅克·普里查德相同的異常:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 

解決其導入兩個cacerts的根證書。 JKS和keystore.jks,使用以下命令:

/usr/java/jdk1.6.0_25/bin/keytool -import -trustcacerts -file root_ca.cer -alias rootca -keystore cacerts.jks 

/usr/java/jdk1.6.0_25/bin/keytool -import -trustcacerts -file root_ca.cer -alias rootca -keystore keystore.jks 

它說,別名rootca是我自己定義的標記證書的名稱是非常重要的。你也可以選擇任何名字。

0

我終於明白了。

從我的keytool中刪除了所有證書。

命令示例:keytool -list -v -keystore keystore.jks -alias mydomain

我轉換證書響應從服務器到bas64 DER和複製他們到一個文件中的.PEM,我上傳的.PEM到我的密鑰工具:

命令示例:keytool -importcert -keystore keystore.jks -alias mydomain -file my.pem

然後我加載密鑰庫:

KeyStore myStore = KeyStore.getInstance("JKS"); 
InputStream keyInputx = new FileInputStream("C:\\myStore.jks"); 
myStore.load(keyInputx, "xxx".toCharArray()); 
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); 
keyInputx.close(); 
/*Enumeration enumeration = myStore.aliases(); 
while (enumeration.hasMoreElements()) { 
    String alias = (String) enumeration.nextElement(); 
    System.out.println("alias name: " + alias); 
    Certificate certificate = myStore.getCertificate(alias); 
    System.out.println(certificate.toString()); 
}*/ 
keyManagerFactory.init(myStore, "xxx".toCharArray()); 
SSLContext context = SSLContext.getInstance("TLS"); 
context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom()); 
SSLSocketFactory sockFact = context.getSocketFactory(); 

大量文獻的周圍所以很高興的使用。

相關問題