2012-09-09 142 views
1

我需要在兩個桌面Java應用程序之間進行通信,並且最好的方法是使用SSL(防止嗅探器)。我控制客戶端和服務器,所以自簽名是好的。Java SSL證書

我的問題是,如果一個證書就可以製備和從頭開始編程使用(即最終用戶不必實際做任何事情他自己)。

如果這是可能的,你能不能給我一些指點?

回答

4

我的問題是,如果一個證書可製成並從頭開始使用 編程(即最終用戶不必在物理做 任何本人)。

在考慮生成證書之前(無論是否通過編程),您需要決定如何驗證它們。在兩個桌面應用程序的環境中,驗證服務器證書的傳統方式可能不合適。

認證證書的目的是給一個方法來驗證遠程方的身份,從而防止人在這方面的中間人攻擊。驗證方使用它已經信任的信息進行驗證;不這樣做使得使用證書毫無意義。

在傳統的模式(具有固定服務器),服務器證書是PKI的一部分,並且由CA頒發客戶端根據其信任的一組CA證書驗證其真實性(通常使用RFC 5280中描述的規則,並驗證該證書對於主機名正在查找的有效(這是如何完成的,取決於協議,但最好和歷史實踐在RFC 6125中有描述),這兩個步驟對於防止MITM攻擊都是必要的,這與使用護照驗證某人的身份類似:您想檢查護照是真實的還是來自您信任的權威機構,並且您想檢查名稱(或圖片)匹配您正在尋找的名稱(或臉在你面前)

在建立兩個桌面應用程序之間的通信,你肯定都會有兩個方面的問題:如何讓客戶驗證證書是由您信任的實體頒發的,併發給了e你想與之通信的實體。如果你沒有任何一方以編程方式生成證書,它肯定會是自簽名的,如果沒有其他交換方式(獨立於此SSL/TLS通信),它將難以從另一方驗證其真實性。另外,桌面往往沒有固定的主機名,所以在這種情況下基於DNS的(甚至是IP地址)標識符可能是不夠的。

您需要想辦法以遠程方驗證信任的方式發佈證書,並考慮識別方案以確保證書屬於正確的實體(這是通常在證書的主題DN或主題備用名稱擴展中出現的內容)。

一旦你做出這些決定,你可以使用BouncyCastleorg.bouncycastle.x509.X509V3CertificateGenerator生成您的證書(X.509的v3證書應該讓你添加擴展的認證,例如對密鑰使用的目的,如果需要的話) 。在BouncyCastle wiki上有各種不同的例子(v1,v3和/或自簽名,即Where Subject = Issuer)。我會說,不幸的是,使用這一點很容易(信任的行政方面將是最困難的)。

如果兩個桌面應用程序實際上更中心的應用程序的兩個部分,你可以運行發出此證書,從您的應用程序中生成的證書請求(CSR)的服務。中央服務器將有效地運行您自己的CA,並且您的桌面應用程序會信任該CA.根據組織的複雜性,可以使用相同的工具來執行此操作,也可以使用BouncyCastle來實現它(如果您實施的CRL/OSCP能夠撤銷證書,它甚至會更好)。在這種情況下,您可以讓您的應用程序生成CSR並將其提交給您的中央CA.使用PKCS10CertificationRequest可以使用BouncyCastle生成CSR。再一次,您的CA如何使用外部信息驗證CSR來自正確的一方,這也是一個管理問題,也許您可​​以將其與電子郵件驗證方案或類似的東西綁定。

生成證書後,您可以使用Java's JSSE作爲SSL/TLS堆棧(通常使用SSLSocket)。您可能必須使用自定義X509TrustManager來實施證書驗證(取決於您如何設計驗證證書的方案,如果無法使用傳統CA模型)。只要確保你不使用在他們的check*方法中不做任何事情的信任管理者;有很多這樣的例子:在這種情況下,如果你沒有做任何事情來驗證它們(這會使得連接易受MITM攻擊),你可能根本不使用證書。

+0

謝謝你的非常詳細的解釋!我的意圖是在我的應用程序的'admin'實例上生成證書,然後將具有可信證書的應用程序副本分發給'judge'。這樣我就可以確切知道哪個證書要信任。 – LanguagesNamedAfterCofee

+0

如果您只有一個「管理」應用程序的實例,可能不值得讓一些代碼生成證書('keytool'可用於生成自簽名證書)。 – Bruno

+0

那麼'admin'將會是一個用戶,他或她的計算機上可能安裝有JDK,也可能沒有JDK。 – LanguagesNamedAfterCofee

1

你可以使用一個基於JCE的解決方案與SSLSocket, docs for jdk6及其實施:SSLSocketImpl。

的Java SSL SSH:

你必須Jsch LIB連接到使用SSH協議的任何服務器。

的Java工具箱SSL:

你有Bouncy Castle。 看看他們的resources和他們的documentation。維基提供some usefull examples了最新版本:

ContentSigner sigGen = ...; 
PublicKey publicKey = ....; 

Date startDate = new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000); 
Date endDate = new Date(System.currentTimeMillis() + 365 * 24 * 60 * 60 * 1000); 

X509v1CertificateBuilder v1CertGen = new JcaX509v1CertificateBuilder(
      new X500Principal("CN=Test"), 
      BigInteger.ONE, 
      startDate, endDate, 
      new X500Principal("CN=Test"), 
      publicKey); 

X509CertificateHolder certHolder = v1CertGen.build(sigGen); 
+1

「* Java的SSL SSH *」:剛指出,SSH無關使用SSL。 (也可能是指JSSE,不JCE) – Bruno

+0

當然,但如果你需要使用SSH + SSL服務器交互,那麼Jsch是一個非常好的圖書館......如果你看看充氣城堡例子,它建立您可以根據需要使用證書。 – ThierryB

+0

雖然我不確定在哪種情況下你需要SSH + SSL。 – Bruno