2016-08-09 44 views
0

我需要集成一個應用程序與強制使用https的外部Web服務。此Web服務的作者爲我提供了.crt文件,我應該使用它來提供https請求。經過一番調查,我發現下面的代碼,它使用KeyStore類爲安全HTTPS訪問:使用KeyStore與.crt

 KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     FileInputStream instream = new FileInputStream(new File(file)); 
     try { 
      trustStore.load(instream, password.toCharArray()); 
     } finally { 
      instream.close(); 
     } 

     SSLContext sslcontext = 
       SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build(); 
     SSLConnectionSocketFactory sslsf = 
       new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1.2"}, null, 
               BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); 
     HttpClients.custom().setSSLSocketFactory(sslsf).build(); 

在這段代碼密鑰庫,需要輸入流與密碼trustStore.load(instream, password.toCharArray())一起。不過,據我所知,使用.crt文件時我們不需要密碼。所以這種加載證書的方式並不適合我。同時,從我迄今爲止發現的情況來看,我在這裏提供的代碼是配置HttpClient使用SSL證書的唯一方法。是否有任何解決方法來配置HttpClient使用.crt證書?

感謝,

安德烈

回答

1

我假定Web服務爲您提供一個自簽名證書(即不是由知名CA簽名)。如果它已經由Java的cacerts文件中的知名CA簽名,則不需要執行任何操作。

否則,你有兩個選擇:

  1. 證書導入全球的cacerts密鑰存儲
  2. 啓動與專用密鑰庫

在這兩種情況下,你首先需要您的應用程序將crt文件轉換爲Java使用的jks keystore。你可以這樣做:

$ keytool -import -keystore mykeystore.jks -storepass horsestaple 

注意,密鑰工具需要創建JKS存儲要提供的密碼(以上horsestaple)。你可以放任何東西;如你所說,公共網站證書不需要密碼保護,畢竟他們是公開的。

如果您正在做選項1,請備份您的cacerts並提供cacerts文件而不是mykeystore.jks。請參閱以下鏈接,瞭解cacerts的位置。對於這個選項,你已經全部設置了,你的應用程序應該通過HTTPS連接到Web服務,而不需要任何額外的配置,因爲默認情況下Java會加載cacerts。

如果你正在做的選項2,這可能是至少首選測試階段,你需要使用這個參數運行應用程序:

-Djavax.net.ssl.trustStore=mykeystore.jks 

這是一個JVM的參數,所以適當地提供它。這取決於你如何運行你的應用程序。

請注意,在這種情況下您將只有導入的證書,因此您的其他HTTPS連接將不起作用。您可以通過首先將標準cacerts複製到臨時位置,將密鑰導入並在上面的命令中使用它來避免這種情況。這將給你所有的標準證書,加上你需要的。

選項2的一個小缺點是,如果新證書被添加或撤銷,您的特定於應用程序的密鑰庫不會被更新。如果這是一個問題,你可以在飛行合併密鑰庫,例如:

在這兩種情況下,你現在應該能夠只是做一個標準的網址提取,如例如在這裏給出:

即:

final URL url = new URL("https://example.com"); 
try(final InputStream in = url.openStream()){ 
    //… 
} 

點擊此處瞭解詳情:

  • 使用Keytool和證書的一般信息

https://docs.oracle.com/cd/E19830-01/819-4712/ablqw/index.html

  • cacerts的位置

http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/keytool.html

  • 更多選擇導入自簽名證書

How to properly import a selfsigned certificate into Java keystore that is available to all Java applications by default?

希望這有助於。

+0

第三種選擇是直接將信任庫用於客戶端API,這是OP看起來像他們正在做的事情。這比你最初提出的兩個選項中的任何一個都好,因爲它不會干擾任何其他信任商店的使用。 –

+0

@ChristopherSchultz同意,如果OP想要使用原來的解決方案,當然可以。我想這取決於用例,如果分佈在多個應用程序中,更新全局cacerts可能會更容易。 –

0

除非他們與應該用於驗證連接他們他們 .crt文件,這表明他們正在使用自簽名證書提供你,他們沒有任何有用您提供。如果需要證書作爲客戶端,您需要的第一件事是公鑰/私鑰對,您可以從中生成一個您簽署的CSR。沒有其他人可以安全地提供除簽名證書之外的任何內容。

如果他們已經提供了自己的(自簽名?)證書,則需要將其加載到一個信任,而不是一個密鑰庫,通過keytool-trustcacerts選項,然後告訴Java使用信任,可以通過javax.net.ssl.trustStore系統屬性或通過構建您自己的TrustManager並將其提供給自定義SSLContext,如JSSE參考指南中所述。