2010-05-10 119 views
8

關於security and trust working group for NHIN Directregarding the IP-to-domain mapping problem that is created with traditional SSL正在進行討論。如果HISP(由NHIN Direct定義)想要爲提供商託管成千上萬的NHIN Direct「健康域名」,那麼它將以「人爲膨脹的成本」不得不爲每個域名購買IP。Java客戶端中具有SNI的TLS

由於Apache和OpenSSL最近發佈了支持SNI擴展的TLS,因此可以使用SNI作爲此問題的解決方案在服務器端。但是,如果我們決定允許允許 NHINDirect傳輸層的服務器實現支持TLS + SNI,那麼我們必須要求所有客戶端都支持SNI。基於OpenSSL的客戶端應該默認執行此操作,並且如果您的給定編程語言SSL實現不支持SNI,我們總是可以通過stunnel實現支持TLS + SNI的客戶端進行代理。看來,使用OpenJDK的原生Java應用程序還不支持SNI,但我無法從該項目中獲得直接的答案。我知道有OpenSSL Java庫可用,但我不知道這是否可行。

您能否給我一個「最先進的」關於Java客戶端的TLS + SNI支持的總結?我需要一個Java實現者的角度來看這個。

回答

3

我正在與ftrotter一起工作。

請注意支持千位的域名要求。我不認爲SAN有兩個原因會削減芥末。首先,證書的大小會變得很大,這可能會至少導致性能問題。其次,這些領域將會頻繁出現,特別是在NHIN Direct早期。恕我直言,每次域名出現或去往時必須更新證書的運營負擔將會變得不可接受。

在ftrotter的請求下,我做了一些關於java,TLS和SNI以及其他實現基於命名的虛擬主機情況的方法,每個虛擬主機有一個證書。以下是我想到的:

  • JSSE(Java安全套接字擴展)支持TLS,並且對TLS + SNI具有「部分支持」。在這種情況下,我不知道部分支持意味着什麼。我看到的評論表明,存在的支持不足以執行基於命名的虛擬主機,這基本上是我們需要的。

  • 我發現一篇文章,聲稱JSSE 的JDK7版本將支持 TLS + SNI(日期2008/11/20),我發現一個聲稱它不會(月2日/二千〇九分之二十七)。兩者都不是特別權威。

  • 一些在OpenJDK 7上工作的人討論了在2009年2月到3月期間向JSSE添加SNI支持的問題,包括髮布源補丁。 (線程從這裏開始: http://www.mail-archive.com/[email protected]/msg00612.html)。 OpenJDK7將不會在2010年9月左右發佈。我不知道Java 7平臺何時發佈。

  • java.sun.com根本沒有什麼實質性的東西,所以我真的不知道Sun的計劃是什麼。

  • 顯然有一種不同的方法可以完成基於名稱的虛擬主機,這種虛擬主機顯然廣泛兼容,每個託管服務器使用一個包含多個通用名稱和多個主題alt名稱的單一證書。見http://wiki.cacert.org/VhostTaskForceServe different certs for same Tomcat application via connectors?

這種做法會造成真正的大證書(由於所有的CN和SAN),如果你有很多虛擬主機。 NHIN Direct最近的面對面會議的一位人士正在談論想要支持虛擬主機的千人。我的猜測是這會打破很多實現。另外,每次添加或刪除虛擬主機時都必須更新證書,這聽起來像是一個荒謬的操作負擔。

總之,每個虛擬主機具有不同證書的基於名稱的虛擬主機的當前Java技術狀態似乎是「不行」。另外,還不清楚何時或是否會添加。

有人同意或不同意嗎?有誰知道OpenJDK項目是否有意向「支持」Java 6的SNI支持?

8
+1

如果你有從服務器(不能在JSSE客戶端被忽略unrecognized_name警報的問題,請參見http://bugs.sun.com/ bugdatabase/view_bug.do?bug_id = 7127374)你可以關閉發送SNI:jsse.enableSNIExtension = false – eckes 2012-01-07 12:43:31

+0

任何想法如何關閉這個小程序? – ivb 2012-05-13 09:01:58

+0

您可以在系統控制面板中爲Applets和WebStart添加(全局)系統屬性。 JNLP文件不能指定不在安全白名單中的系統參數。 (我認爲這個列表可以在某個地方修改,但那不是官方的界面)。 – eckes 2012-06-14 05:50:32

6

,也可以用一些線條的原稿的Sun JDK修補(引導類路徑)來獲得服務器SNI的工作。

類別:sun.security.ssl.ServerHandshaker

添加字段

/** Use for SNI */ 
    private ServerNameExtension serverNameExtension = null; 

修補方法的ClientHello(添加這些行)

/* Use for SNI */ 
    this.serverNameExtension = (ServerNameExtension)mesg.extensions.get(ExtensionType.EXT_SERVER_NAME); 

修補方法setupPrivateKeyAndChain(變化)

if (this.conn != null) { alias = km.chooseServerAlias(algorithm  , null, this.conn); 
    } else     { alias = km.chooseEngineServerAlias(algorithm, null, this.engine); } 

to 

    final Principal[] principals = (this.serverNameExtension == null) ? null : this.serverNameExtension.getHostnamePrincipals(); 
    if (this.conn != null) { alias = km.chooseServerAlias(algorithm  , principals, this.conn); 
    } else     { alias = km.chooseEngineServerAlias(algorithm, principals, this.engine); } 

添加到類sun.security.ssl.ServerNameExtension

static final class ServerNamePrincipal implements Principal { 
    private final String name; 
    ServerNamePrincipal(final String name) { this.name = name; } 
    @Override public String getName() { return this.name; } 
    @Override public String toString() { return this.name; } 
} 

public Principal[] getHostnamePrincipals() { 
    final List<Principal> principals = new LinkedList<>(); 
    for(final ServerName name : this.names) { 
     if(name.type == NAME_HOST_NAME) { principals.add(new ServerNamePrincipal(name.hostname)); } 
    } 
    return principals.toArray(new Principal[principals.size()]); 
}