2012-01-25 79 views
6

我目前正在服務器具有默認的自簽名SSL證書的測試環境中工作。我使用的Restlet 2.1-RC2和實例的客戶資源是這樣的:每個呼叫我做如何使Restlet客戶端忽略SSL證書問題

Client client = new Client(new Context(), Protocol.HTTP); 
cr = new ClientResource(String.format(itql_endpoint,riQuery)); 
cr.setNext(client); 

和重用客戶端。我如何設置客戶端以便忽略有問題的證書。

+2

沒有 - 我特別詢問有關如何使用Restlet框架做到這一點( http://www.restlet.org/)。我在其他場合使用其他類型的連接,我只是想知道用Restlet – nwaltham

+0

道歉的方法,但我不知道該怎麼做。 。 – home

回答

9

正確的方法是導入該自簽名證書到客戶端的信任存儲,例如使用keytool

keytool -import -file server-cert.pem -alias myserver -keystore mytruststore.jks 

你可以做到這一點直接在JRE的信任存儲(lib/security/cacerts)這可能缺乏一些靈活性,或者在您自己的此文件副本中執行此操作,然後將其設置爲信任存儲區(OSX上的默認密碼爲changeitchangeme)。你爲你的應用程序使用通常的javax.net.ssl.trustStore*系統屬性全局配置此信任(如-Djavax.net.ssl.trustStore=mytruststore系統屬性(和-Djavax.net.ssl.trustStorePassword),也可以使用服務器的上下文參數中的Restlet特定連接器配置,例如:

Series<Parameter> parameters = client.getContext().getParameters(); 
parameters.add("truststorePath", "/path/to/your/truststore.jks"); 
// parameters.add("truststorePassword", "password"); 
// parameters.add("trustPassword", "password"); 
// parameters.add("truststoreType", "JKS"); 

錯誤的方式是使用TrustManager那將禁用任何驗證,並通過SslContextFactory傳遞(在SSL擴展)。這些方針的東西。

TrustManager tm = new X509TrustManager() { 
    public void checkClientTrusted(X509Certificate[] chain, 
        String authType) 
        throws CertificateException { 
    } 

    public X509Certificate[] getAcceptedIssuers() { 
     return new X509Certificate[0]; 
    } 

    public void checkServerTrusted(X509Certificate[] chain, 
        String authType) 
        throws CertificateException { 
     // This will never throw an exception. 
     // This doesn't check anything at all: it's insecure. 
    } 
}; 

final SSLContext sslContext = SSLContext.getInstance("TLS"); 
sslContext.init(null, new TrustManager[] {tm}, null); 
Context context = client.getContext(); 
context.getAttributes().put("sslContextFactory", new SslContextFactory() { 
    public void init(Series<Parameter> parameters) { } 
    public SSLContext createSslContext() { return sslContext; } 
}); 

雖然第一種方法看起來比第二種方法更乏味(因爲您需要首先獲取服務器證書並複製文件),但第二種方法只會通過不驗證有關服務器證書的任何內容而使錯誤消息消失,使其容易受到主動MITM攻擊。這將適用於配置此SSLContext的任何連接。 (這個「錯誤的做法是沒有錯的,因爲它使用了自定義SSLContext,這是因爲SSLContext的這種特定配置的錯誤。)

+0

非常感謝。非常完整的答案!不幸的是,現在卡住javax.net.ssl.SSLException:證書中的主機名不匹配。似乎沒有辦法解決這個問題:http://restlet.tigris.org/issues /show_bug.cgi?id=1078 – nwaltham

+2

我必須承認我不記得我的頭頂如何tw剔除主機名稱驗證。最好的方法是使用正確名稱的自簽名證書。通常,只需在主題DN中設置CN即可,但您也可以設置主題備用名稱(如果使用IP地址,您將需要它),請參閱http://stackoverflow.com/a/8444863/372643 – Bruno

+0

我在Android中使用了自簽名證書,此解決方案與http://developer.android.com/training/articles/security-ssl.html#SelfSigned相結合解決了我的問題。非常感謝! – user1226868

1
// Create all-trusting host name verifier 
HostnameVerifier allHostsValid = new HostnameVerifier() { 
     public boolean verify(String hostname, SSLSession session) { 
     return true; 
     } 
    }; 
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);