2011-07-25 37 views
4

我知道如何使用證書來保護Web服務。這是我的客戶代碼:如何通過Web服務製作簡單的SSL?

SSLContext ssl = SSLContext.getInstance("SSLv3"); 
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
    KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType()); 
    String password = Configuration.getConfig("keyStorePassword"); 
    store.load(new FileInputStream(new File(Configuration.getConfig("keyStore"))), password.toCharArray()); 
    kmf.init(store, password.toCharArray()); 
    KeyManager[] keyManagers = new KeyManager[1]; 
    keyManagers = kmf.getKeyManagers(); 
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
    tmf.init(store); 
    TrustManager[] trustManagers = tmf.getTrustManagers(); 
    ssl.init(keyManagers, trustManagers, new SecureRandom()); 

    HttpsConfigurator configurator = new HttpsConfigurator(ssl); 
    Integer port = Integer.parseInt(Configuration.getConfig("port")); 
    HttpsServer httpsServer = HttpsServer.create(new InetSocketAddress(Configuration.getConfig("host"), port), 0); 
    httpsServer.setHttpsConfigurator(configurator); 

    Implementor implementor = new Implementor(); // class with @WebService etc. 
    HttpContext context = (HttpContext) httpsServer.createContext("/EventWebService"); 
    Endpoint endpoint = Endpoint.create(implementor); 
    endpoint.publish(context); 

現在,如何使'簡單的SSL'?如何在客戶端不存儲證書的情況下進行SSL連接。 (如通過瀏覽器中的HTTPS連接)

回答

5

Java Runtime Environment在cacerts文件中附帶了許多(最廣泛使用的)證書頒發機構。如果您用來保護您的服務的證書由其中一個根CA簽署,那麼您無需擔心與客戶共享任何證書。

但是,如果您使用自簽名的證書,你不希望傳遞信任/導入證書,那麼你可以實現自定義X509TrustManager併爲您的連接創建自定義的SSLContext。更多詳情請見blog

自簽名證書是開發和測試環境有用的,但你真的應該考慮讓從認可的證書頒發機構如Verisign,Thwate的等

+0

我認爲TrustAlmostEverythingManager就是我正在尋找的東西。 我用精確的IP連接到服務器(所以不可能有人會欺騙)。我只是想保護連接免受竊聽。 我想對嗎?也許在將來,將需要生成客戶端和服務器證書。 – razor

+0

嗯......是的,但是如果您的Web服務消費者不在您的組織之中,那麼他們相信自簽名證書會更加困難。我建議提前掏出幾塊錢,讓你的客戶感覺更好。我也建議獲得一個合適的域名,而不是共享一個帶有IP地址的WSDL。自簽名證書非常適合Intranet應用程序和測試環境,但對於外部客戶而言,額外的一些額外費用將會很長! – helios

+0

客戶在組織之外,爲什麼信任是困難的?你的意思是很難驗證服務器? 我知道來自CA的證書會更好,而且這個環境的管理員也知道。 現在,它只是不依賴於我。也許,將來會有適當的證書(由CA頒發)等。 – razor

0

只需與HTTPS建立連接即可。只要客戶使用標準的可信任證書,它就可以正常工作。如果他們有自簽名證書,則需要將證書導入到java密鑰庫中。

+0

我想製作安全的Web服務,但我不想在客戶機上放置任何證書。我想通過HTTPS連接到瀏覽器等服務器。客戶端和服務器是由我寫的,我可以改變它。 – razor

+0

我的意思是:簡單的TLS握手http://en.wikipedia.org/wiki/Transport_Layer_Security – razor

+0

瀏覽器擁有預先安裝在其中的公共可信證書,Java密鑰庫也是如此。他們不會動態協商他們......否則他們不會被信任。 – ryber

2

如果我的理解正確,那麼您希望只使用服務器端身份驗證,就像您在瀏覽器中連接到https站點一樣,而不需要客戶端來管理任何證書。

您的客戶端將像往常一樣進行連接,只需將連接URL中的https替換爲http即可。 Java以cacerts(位於$JRE HOME/lib/security中的JKS密鑰庫文件)的形式管理其自己的一組「默認可信根CA授權」。如果您從任何發行證書根據cacerts中包含的證書之一購買CA的證書,則客戶證書驗證將自動成功。谷歌的「SSL/TLS服務器證書」,你會找到合適的供應商。

另一方面,如果您要使用自行頒發的證書,則除了在客戶端的證書信任庫中導入自制證書之外,無法在客戶端上使證書驗證成功。但這就是爲什麼一個「真正的」SSL/TLS證書花錢並且你的自發證書沒有 - 任何人都可以生成他們的本土證書,但相信它們是一個完全不同的故事。

0

HTTPS瀏覽器中籤名的服務器證書有效,因爲有含有信任客戶端上的SSL證書。換句話說:有證書存儲在客戶端。

如果你想HTTPS沒有任何證書存儲在客戶端,我認爲你應該看看this article,它解釋瞭如何關閉HTTPS連接的默認證書驗證。

1

如果在HTTPS服務器需要這樣的客戶端證書,您可以控制:

HttpsConfigurator cfg = new HttpsConfigurator(sslCtx){ 
    public void configure(HttpsParameters params) { 
     SSLParameters sslparams = getSSLContext().getDefaultSSLParameters(); 

     // Modify the default params: 
     // Using this, server will require client certs 
     //sslparams.setNeedClientAuth(true); 

     // Using this, server will request client certs. But if not available, 
     // it will continue anyway. 
     sslparams.setWantClientAuth(true); 

     params.setSSLParameters(sslparams); 
    } 
}; 
HttpsServer httpsS = HttpsServer.create(new InetSocketAddress(8081), 50); 
httpsS.setHttpsConfigurator(cfg); 

如果不需要客戶端證書,客戶端可以連接而無需客戶端證書,就這麼簡單調用HTTPS會工作。

在我的博客中,您可以看到如何繞過服務器證書和主機名驗證的客戶端示例(儘管不推薦使用,例如,用於測試) http://jakubneubauer.wordpress.com/2011/09/06/java-webservice-over-ssl/