2013-02-13 87 views
6

我的事實,我對設置密鑰庫等在Java中調用WebService的,並具有SSL /證書問題

我試圖調用一個SOAP Web服務沒有太大的知識開始,我得到了WSDL ,生成代碼等。一切似乎都沒有問題,直到我部署它並嘗試觸發WS調用。

這裏是我的設置:

  • 的Tomcat 7.0.35
  • 的Java,JDK 1.6.0_39
  • PFX文件,並部署爲標準的Web應用程序(WAR)密碼
  • 項目到Tomcat

當我運行代碼時,我得到以下異常:

Caused by: javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking https://tallyservices-qa.olson.com/tallyDemo2WebServices/tallyDemo2/sms: Received fatal alert: certificate_unknown 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513) 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1336) 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1320) 
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) 
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:622) 
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62) 
    ... 27 more 
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown 
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) 
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1837) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1019) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1203) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1230) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1214) 
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434) 
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166) 
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1031) 
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230) 
    at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.setupWrappedStream(URLConnectionHTTPConduit.java:170) 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1280) 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1231) 
    at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:183) 
    at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47) 
    at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69) 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1293) 
    ... 30 more 

我跟着建議在這裏:How to convert .pfx file to keystore with private key?的證書安裝到我的密鑰庫:

keytool -importkeystore -srckeystore C:\somefolder\mypfxfile.pxf -srcstoretype pkcs12 
-destkeystore C:\somefolder\clientcert.jks -deststoretype JKS 

和我:

Enter destination keystore password: <mypassword> 
Re-enter new password: <mypassword> 
Enter source keystore password: <pxf_password> 
Entry for alias 67eb31f6 successfully imported. 
Import command completed: 1 entries successfully imported, 0 entries failed or 
cancelled 

所以,一切看起來很不錯,到目前爲止,我彈我的Tomcat和再次擊中Servlet,我仍然得到相同的錯誤。

我還有什麼在這裏失蹤?我需要告訴tomcat關於證書的事嗎?

在此先感謝您在密鑰倉庫和證書區域爲我提供的幫助和道歉。

編輯: 所以我從卡羅Pellegrini`s幫助想通,我需要添加密鑰存儲到tomcat:所以現在 ,我的Tomcat是開始額外JAVA_OPTS參數:

"-Djavax.net.ssl.trustStore=C:\somefolder\clientcert.jks -Djavax.net.ssl.trustStorePassword=somepassword" 

和現在,我得到:

Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty 

從這裏:Error - trustAnchors parameter must be non-emptygot java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty when using cas - 好像我的信任是不是發現了什麼?

我想我剛纔的命令:

keytool -importkeystore -srckeystore C:\somefolder\mypfxfile.pxf -srcstoretype pkcs12 -destkeystore C:\somefolder\clientcert.jks -deststoretype JKS 

其實把PXF到密鑰庫,不信任?

當我檢查密鑰庫列表:

C:\somefolder>keytool -list -keystore "C:\somefolder\clientcert.jks" 
Enter keystore password: 

Keystore type: JKS 
Keystore provider: SUN 

Your keystore contains 1 entry 

67eb31f6, 13-Feb-2013, PrivateKeyEntry, 
Certificate fingerprint (MD5): ... some fingerprint ... 

所以我不知道我是什麼在這裏失蹤

+0

我不知道在這種情況下的確切設置,但是如果您使用私鑰註冊或加密消息,則服務器應該有公鑰。如果它只是ssl/tls,正如例外情況所示,服務器證書可能不受信任? – jhexp 2013-02-13 16:52:30

回答

3

我發現解決方案,我應該使用keyStore而不是比的trustStore,但更重要的是,似乎有與我使用,我必須直接在代碼中設置了SSL屬性庫(CXF 2.7.1)的問題:

// BEGIN FIX to avoid certificate error, need to set this up in the code for cxf 
String storePath = System.getProperty("javax.net.ssl.keyStore"); 
String storePassword = System.getProperty("javax.net.ssl.keyStorePassword"); 
String storeType = System.getProperty("javax.net.ssl.keyStoreType"); 
KeyStore keyStore = KeyStore.getInstance(storeType); 
keyStore.load(new FileInputStream(storePath), storePassword.toCharArray()); 
KeyManagerFactory factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
factory.init(keyStore, storePassword.toCharArray()); 
KeyManager[] keyManagers = factory.getKeyManagers(); 
Client client = ClientProxy.getClient(port); 
HTTPConduit conduit = (HTTPConduit) client.getConduit(); 
conduit.setTlsClientParameters(new TLSClientParameters()); 
conduit.getTlsClientParameters().setKeyManagers(keyManagers); 
5

你需要信任服務器證書。這裏是如何做到這一點:

使用Chrome(其他borwsers指令可能會有所不同):

  • 衝浪到服務站點。 (例如,https://localhost/myService
  • 如果瀏覽器不信任它,單擊Proceed anyway,點擊你的地址欄的掛鎖圖標,並沒有彈出的窗口中,選擇Connection標籤和Certificate Information鏈接。
  • 這應該打開證書查看器窗口,其中,選擇Details,您應該查看Export ...按鈕。選擇Base 64編碼的單一證書並將其保存爲mysite.cer文件。

這將獲得證書,現在您需要將其導入到信任庫中。

現在導入密鑰庫證書:

keytool -import -file mysite.cer -keystore mykeystore 

這會在當前目錄中的新文件的密鑰存儲文件mykeystore

最後推出使用JVM參數javax.net.ssl.trustStore Web服務客戶端應用程序,如:

java -Djavax.net.ssl.trustStore=mykeystore ... MyClientClass 

或者,如果你在Windows中使用Tomcat:

set JAVA_OPTS=-Djavax.net.ssl.trustStore=mykeystore 
startup.bat 

或者,如果你是在Unix的使用Tomcat :

export JAVA_OPTS="-Djavax.net.ssl.trustStore=mykeystore" 
startup.sh 
+0

在這種情況下,Web服務客戶端是我的Tomcat?因爲我的web應用程序連接到web服務在tomcat中運行。我如何設置tomcat來查看密鑰庫? – 2013-02-13 18:17:17

+0

根據您的要求進行編輯。 – 2013-02-13 18:32:02

+0

謝謝,我取得了進展......但似乎現在我碰到了truststore vs keystore問題 – 2013-02-13 20:30:38